STM32CubeH7
STM32CubeH7 copied to clipboard
Enhancement: Provide a function that is capable of storing multiple CAN messages to CAN TX FIFOs before updating TXBAR
Hello,
I am trying to find a function that helps first find all available TX FIFOs and later fills them with (Classic) CAN Data and Extended IDs before updating a value to hfdcan->Instance->TXBAR. This code will be helpful to me in the long run.
There are only two functions in file stm32h7xx_hal_fdcan.c that modify value of hfdcan->Instance->TXBAR. The two functions are namely HAL_FDCAN_AddMessageToTxFifoQ() , and HAL_FDCAN_EnableTxBufferRequest()
HAL_FDCAN_AddMessageToTxFifoQ() seems to update only one FIFO and then transmit its data.
HAL_FDCAN_EnableTxBufferRequest() seems to only update hfdcan->Instance->TXBAR
I am unable to find a function that calls FDCAN_CopyMessageToRAM() multiple times to fill the CAN TX FIFOs before updating TXBAR
Please help implement above request.
Thanks, @rxa1031
Hello,
Is it possible to change the static typecast for FDCAN_CopyMessageToRAM() and change it to just:
void FDCAN_CopyMessageToRAM(FDCAN_HandleTypeDef *hfdcan, FDCAN_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData, uint32_t BufferIndex)
and extern it.
Please suggest.
Thanks, @rxa1031
Hello,
As the requested code piece / function was not available, I had to code a custom / my own function for this.
May I share the coded custom function here?
Regards, @rxa1031
Hello @rxa1031,
Thank you for your contribution. Your report will be forwarded to our development team for analyzis and if confirmed the fix will be deployed on new STM32Cube series under dev. We will get back to you as soon as we have an answer.
Thanks in advence for your patience and understanding.
With Regards, KORKAD
ST Internal Reference: 121056
Dear ST,
Attached is the modified CAN driver that I’ve been using.
Please refer to function CRC_Evans_FDCAN_AddMultipleMessagesToTxFifoQ() and suggest whether the implementation is correct.
Regards, Rajeev
From: ASELSTM @.> Sent: Monday, January 17, 2022 9:22 PM To: STMicroelectronics/STM32CubeH7 @.> Cc: Arora, Rajeev (BLR) @.>; Mention @.> Subject: Re: [STMicroelectronics/STM32CubeH7] Enhancement: Provide a function that is capable of storing multiple CAN messages to CAN TX FIFOs before updating TXBAR (#157)
External Message, L00k Carefully.
ST Internal Reference: 121056
— Reply to this email directly, view it on GitHubhttps://urldefense.com/v3/__https:/github.com/STMicroelectronics/STM32CubeH7/issues/157*issuecomment-1014682212__;Iw!!JCruJraw!bnoJO9_9FrvA13yOMZdOpVusoA1a4MSdaO90NboDRoHrYlzxs0OeXB0JEiE4WcNUtX0$, or unsubscribehttps://urldefense.com/v3/__https:/github.com/notifications/unsubscribe-auth/AEKRY42VYC5VP36ADPTASDTUWQ3JVANCNFSM46MA2ZZA__;!!JCruJraw!bnoJO9_9FrvA13yOMZdOpVusoA1a4MSdaO90NboDRoHrYlzxs0OeXB0JEiE43O2ttGw$. Triage notifications on the go with GitHub Mobile for iOShttps://urldefense.com/v3/__https:/apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675__;!!JCruJraw!bnoJO9_9FrvA13yOMZdOpVusoA1a4MSdaO90NboDRoHrYlzxs0OeXB0JEiE4n87_ROQ$ or Androidhttps://urldefense.com/v3/__https:/play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign*3Dnotification-email*26utm_medium*3Demail*26utm_source*3Dgithub__;JSUlJSU!!JCruJraw!bnoJO9_9FrvA13yOMZdOpVusoA1a4MSdaO90NboDRoHrYlzxs0OeXB0JEiE4aRaLYXs$. You are receiving this because you were mentioned.Message ID: @.@.>>
#include "../inc/Includes.H"
#if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
//volatile uint32_t g_u32ThisPSCAliveCMI; //volatile uint32_t g_ReadCAN_CMI;
if defined(dTestOnlyCANRx)
uint32_t gu32CANRxCounts = 0; uint32_t gu32RxFifo0ITs = 0;
endif // of defined(dTestOnlyCANRx)
#define dDeclareTestCAN_Messages( CAN_Port )
bool bCAN##CAN_Port##IsPSCAliveMessageReceived = false;
uint8_t u8CAN##CAN_Port##CurrentMessageMakerValue = 0;
/* PSC is Alive response header. /
const FDCAN_TxHeaderTypeDef gNoCAN##CAN_Port##PSCIsAliveResponseTxHeader =
{
.Identifier = dCAN##CAN_Port##PSCIsAliveTxID, /!< Specifies the identifier.
This parameter must be a number between:
- 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
- 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID /
.IdType = FDCAN_EXTENDED_ID, /!< Specifies the identifier type for the message that will be
transmitted.
This parameter can be a value of @ref FDCAN_id_type /
.TxFrameType = FDCAN_DATA_FRAME, /!< Specifies the frame type of the message that will be transmitted.
This parameter can be a value of @ref FDCAN_frame_type /
.DataLength = dDummyDataLength, /!< Specifies the length of the frame that will be transmitted.
This parameter can be a value of @ref FDCAN_data_length_code /
.ErrorStateIndicator = FDCAN_ESI_ACTIVE, /!< Specifies the error state indicator.
This parameter can be a value of @ref FDCAN_error_state_indicator /
.BitRateSwitch = FDCAN_BRS_OFF, /!< Specifies whether the Tx frame will be transmitted with or without
bit rate switching.
This parameter can be a value of @ref FDCAN_bit_rate_switching /
.FDFormat = FDCAN_CLASSIC_CAN, /!< Specifies whether the Tx frame will be transmitted in classic or
FD format.
This parameter can be a value of @ref FDCAN_format /
.TxEventFifoControl = dReqdCAN##CAN_Port##TxEventFIFOControlState, /!< Specifies the event FIFO control.
This parameter can be a value of @ref FDCAN_EFC /
.MessageMarker = dDummyMessageMaker /!< Specifies the message marker to be copied into Tx Event FIFO
element for identification of Tx message status.
This parameter must be a number between 0 and 0xFF */
};
if ( 1 == MX_FDCAN1 )
dDeclareTestCAN_Messages( 1 );
endif // of ( 1 == MX_FDCAN1 )
if ( 1 == MX_FDCAN2 )
dDeclareTestCAN_Messages( 2 );
endif // of ( 1 == MX_FDCAN2 )
#endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
#if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE) || (DRA_ENABLE_GATEWAY_CODE == DRA_ENABLE_CODE)
#define dDeclareCAN_Variables( CAN_Port )
static bool bCAN##CAN_Port##ErrorAbortTx = false;
bool bCAN##CAN_Port##WaterMarkReached = false;
uint8_t u8MaxExtendedCAN##CAN_Port##Filters = 2;
uint8_t u8MaxStandardCAN##CAN_Port##Filters = 0;
uint32_t CapturedCAN##CAN_Port##TxEventFIFOITs;
static FDCAN_RxHeaderTypeDef oCAN##CAN_Port##RxHeader;
static uint8_t au8CAN##CAN_Port##Payload[8];
FDCAN_TxEventFifoTypeDef CheckCAN##CAN_Port##TxEvtFIFO[32];
struct _oN_ErrorsAndErrorStatuses goN_CAN##CAN_Port##ErrorsAndErrorStatuses;
static FDCAN_FilterTypeDef gNoClassicCAN##CAN_Port##ReceiveMessageFilters[] =
{
{
.IdType = FDCAN_EXTENDED_ID, /*!< Specifies the identifier type.
This parameter can be a value of @ref FDCAN_id_type /
/ #DRA: Dummy value. This variable is updated inside function rvCRC_Evans_FDCAN_ConfigFiler() /
.FilterIndex = 0, /!< Specifies the filter which will be initialized.
This parameter must be a number between:
- 0 and 127, if IdType is FDCAN_STANDARD_ID
- 0 and 63, if IdType is FDCAN_EXTENDED_ID /
.FilterType = FDCAN_FILTER_MASK, /!< Specifies the filter type.
This parameter can be a value of @ref FDCAN_filter_type.
The value FDCAN_EXT_FILTER_RANGE_NO_EIDM is permitted
only when IdType is FDCAN_EXTENDED_ID.
This parameter is ignored if FilterConfig is set to
FDCAN_FILTER_TO_RXBUFFER /
.FilterConfig = dCAN##CAN_Port##RxIsPSCAliveQueryWriteToFIFO, /!< Specifies the filter configuration.
This parameter can be a value of @ref FDCAN_filter_config /
.FilterID1 = dCAN##CAN_Port##IsPSCAliveFilterID, /!< Specifies the filter identification 1.
This parameter must be a number between:
- 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
- 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID /
.FilterID2 = dIsPSCAliveMaskID, /!< Specifies the filter identification 2.
This parameter is ignored if FilterConfig is set to
FDCAN_FILTER_TO_RXBUFFER.
This parameter must be a number between:
- 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
- 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID /
/ Dummy data /
.RxBufferIndex = 0, /!< Contains the index of the Rx buffer in which the
matching message will be stored.
This parameter must be a number between 0 and 63.
This parameter is ignored if FilterConfig is different
from FDCAN_FILTER_TO_RXBUFFER /
/ Dummy data /
.IsCalibrationMsg = 0 /!< Specifies whether the filter is configured for
calibration messages.
This parameter is ignored if FilterConfig is different
from FDCAN_FILTER_TO_RXBUFFER.
This parameter can be:
- 0 : ordinary message
- 1 : calibration message /
},
{
.IdType = FDCAN_EXTENDED_ID, /!< Specifies the identifier type.
This parameter can be a value of @ref FDCAN_id_type /
/ #DRA: Dummy value. This variable is updated inside function rvCRC_Evans_FDCAN_ConfigFiler() /
.FilterIndex = 1, /!< Specifies the filter which will be initialized.
This parameter must be a number between:
- 0 and 127, if IdType is FDCAN_STANDARD_ID
- 0 and 63, if IdType is FDCAN_EXTENDED_ID /
.FilterType = FDCAN_FILTER_MASK, /!< Specifies the filter type.
This parameter can be a value of @ref FDCAN_filter_type.
The value FDCAN_EXT_FILTER_RANGE_NO_EIDM is permitted
only when IdType is FDCAN_EXTENDED_ID.
This parameter is ignored if FilterConfig is set to
FDCAN_FILTER_TO_RXBUFFER /
.FilterConfig = dCAN##CAN_Port##RxGatewayIDMachWriteToFIFO, /!< Specifies the filter configuration.
This parameter can be a value of @ref FDCAN_filter_config /
.FilterID1 = dCAN##CAN_Port##GatewayFilterID, /!< Specifies the filter identification 1.
This parameter must be a number between:
- 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
- 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID /
.FilterID2 = dGatewayMaskID, /!< Specifies the filter identification 2.
This parameter is ignored if FilterConfig is set to
FDCAN_FILTER_TO_RXBUFFER.
This parameter must be a number between:
- 0 and 0x7FF, if IdType is FDCAN_STANDARD_ID
- 0 and 0x1FFFFFFF, if IdType is FDCAN_EXTENDED_ID /
/ Dummy data /
.RxBufferIndex = 0, /!< Contains the index of the Rx buffer in which the
matching message will be stored.
This parameter must be a number between 0 and 63.
This parameter is ignored if FilterConfig is different
from FDCAN_FILTER_TO_RXBUFFER /
/ Dummy data /
.IsCalibrationMsg = 0 /!< Specifies whether the filter is configured for
calibration messages.
This parameter is ignored if FilterConfig is different
from FDCAN_FILTER_TO_RXBUFFER.
This parameter can be:
- 0 : ordinary message
- 1 : calibration message */
}
};
if ( 1 == MX_FDCAN1 )
dDeclareCAN_Variables( 1 );
endif // of ( 1 == MX_FDCAN1 )
if ( 1 == MX_FDCAN2 )
dDeclareCAN_Variables( 2 );
endif // of ( 1 == MX_FDCAN2 )
if ((1 == MX_FDCAN1) || (1 == MX_FDCAN2))
//---------------------------------------------------------------------------------------------
// #DRA: // // NOTES: // // The FDCAN calculates the Tx FIFO free level FDCAN_TXFQS.TFFL as difference between get and // put index. New transmit messages have to be written to the Tx FIFO starting with the Tx // buffer referenced by the put index FDCAN_TXFQS.TFQPI. // // FDCAN Tx FIFO/queue status register (FDCAN_TXFQS) // The Tx FIFO/queue status is related to the pending Tx requests listed in register // FDCAN_TXBRP. Therefore the effect of add/cancellation requests may be delayed due to a // running Tx scan (FDCAN_TXBRP not yet updated). // // IMPORTANT: // // 1. When a single message is added to the Tx FIFO, the transmission is requested by writing a // 1 to the FDCAN_TXBAR bit related to the Tx buffer referenced by the Tx FIFO put index. // // 2. When multiple (n) messages are added to the Tx FIFO, they are written to n consecutive Tx // buffers starting with the put index. The transmissions are then requested via // FDCAN_TXBAR. The put index is then cyclically incremented by n. The number of // requested Tx buffers should not exceed the number of free Tx buffers as indicated by the Tx // FIFO free level. //
if defined(dAddMultipleTxCANMessagesToFIFO)
// //- - - - - - - - CRC_Evans_CheckTxFifoLevel - - - - - - - // uint32_t CRC_Evans_CheckTxFifoLevel(FDCAN_HandleTypeDef* hfdcan, uint32_t * pu32FreeLevel, bool * pErrorAbortTx, toN_ErrorsAndErrorStatuses * poN_ErrorsAndErrorStatuses) { int iRetries = 0; uint32_t u32FDCAN_IR_Flags = 0; /* Get number of consecutive free Tx FIFO elements starting from Tx FIFO GetIndex. / / Free Level is the number of FIFOs that are available to receive the Tx CAN Frames. */ while (0 == ((*pu32FreeLevel) = HAL_FDCAN_GetTxFifoFreeLevel(hfdcan))) { if ((dCANRetryCounts == iRetries) && (false == (pErrorAbortTx))) { assert_failed((uint8_t)FILE, LINE); break; } else if ((false == (*pErrorAbortTx)) && (0 != (hfdcan->Instance->IR & (FDCAN_ERROR_FLAGS)))) { u32FDCAN_IR_Flags = poN_ErrorsAndErrorStatuses->u32CurrentFDCAN_IR_Value | (hfdcan->Instance->IR & (FDCAN_ERROR_FLAGS)); break; } else if (true == (*pErrorAbortTx)) { u32FDCAN_IR_Flags = poN_ErrorsAndErrorStatuses->u32CurrentFDCAN_IR_Value; break; } else { HAL_Delay(1); } iRetries++; } return u32FDCAN_IR_Flags; }
// //- - - - - - - - CRC_Evans_FDCAN_AddMultipleMessagesToTxFifoQ - - - - - - - // CRC_StatusTypeDef CRC_Evans_FDCAN_AddMultipleMessagesToTxFifoQ(FDCAN_HandleTypeDef* hfdcan, uint32_t u32NumberOfMessagesToAddToTxFIFO, FDCAN_TxHeaderTypeDef* pTxHeader, uint8_t* pTxData) { bool* pErrorAbortTx = NULL; toN_ErrorsAndErrorStatuses* poN_ErrorsAndErrorStatuses = NULL; CRC_StatusTypeDef nStatus; uint32_t u32FDCAN_IR_Flags = 0; uint32_t u32FreeLevel = 0;
switch((uint32_t)hfdcan->Instance)
{
default:
{
assert_failed((uint8_t *)__FILE__, __LINE__);
break;
}
if (1 == MX_FDCAN1)
case (uint32_t)(FDCAN1):
{
pErrorAbortTx = &bCAN1ErrorAbortTx;
poN_ErrorsAndErrorStatuses = &goN_CAN1ErrorsAndErrorStatuses;
}
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
case (uint32_t)(FDCAN2):
{
pErrorAbortTx = &bCAN2ErrorAbortTx;
poN_ErrorsAndErrorStatuses = &goN_CAN1ErrorsAndErrorStatuses;
}
endif // of (1 == MX_FDCAN2)
}
nStatus.hs = HAL_ERROR;
if ((1 == u32NumberOfMessagesToAddToTxFIFO) && (false == (*pErrorAbortTx)))
{
u32FDCAN_IR_Flags = CRC_Evans_CheckTxFifoLevel(hfdcan, &u32FreeLevel, pErrorAbortTx, poN_ErrorsAndErrorStatuses);
if (0 == u32FDCAN_IR_Flags)
{
nStatus.hs = HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, pTxHeader, pTxData);
}
}
else if ((1 < u32NumberOfMessagesToAddToTxFIFO) && (false == (*pErrorAbortTx)))
{
uint32_t u32CurrentPutIndex = 0;
uint32_t u32CollatedPutIndexes = 0;
uint32_t u32TotalMessagesAddedToFIFO = 0;
do
{
if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
{
FDCAN_TxHeaderTypeDef* pThisTxHeader = pTxHeader;
uint32_t u32MessagesToCheck = u32NumberOfMessagesToAddToTxFIFO;
while ((0 != u32MessagesToCheck) && (false == (*pErrorAbortTx)))
{
/* Check function parameters */
assert_param(IS_FDCAN_ID_TYPE(pThisTxHeader->IdType));
if (pThisTxHeader->IdType == FDCAN_STANDARD_ID)
{
assert_param(IS_FDCAN_MAX_VALUE(pThisTxHeader->Identifier, 0x7FFU));
}
else /* pThisTxHeader->IdType == FDCAN_EXTENDED_ID */
{
assert_param(IS_FDCAN_MAX_VALUE(pThisTxHeader->Identifier, 0x1FFFFFFFU));
}
assert_param(IS_FDCAN_FRAME_TYPE(pThisTxHeader->TxFrameType));
assert_param(IS_FDCAN_DLC(pThisTxHeader->DataLength));
assert_param(IS_FDCAN_ESI(pThisTxHeader->ErrorStateIndicator));
assert_param(IS_FDCAN_BRS(pThisTxHeader->BitRateSwitch));
assert_param(IS_FDCAN_FDF(pThisTxHeader->FDFormat));
assert_param(IS_FDCAN_EFC(pThisTxHeader->TxEventFifoControl));
assert_param(IS_FDCAN_MAX_VALUE(pThisTxHeader->MessageMarker, 0xFFU));
pThisTxHeader++;
if (true == (*pErrorAbortTx))
{
break;
}
u32MessagesToCheck--;
}
if (0 < u32MessagesToCheck)
{
break;
}
// Resetting value stored with variable
u32FreeLevel = 0;
while ((0 != u32NumberOfMessagesToAddToTxFIFO) && (false == (*pErrorAbortTx)))
{
if(0 == u32FreeLevel)
{
u32FDCAN_IR_Flags = CRC_Evans_CheckTxFifoLevel(hfdcan, &u32FreeLevel, pErrorAbortTx, poN_ErrorsAndErrorStatuses);
if ((0 != u32FDCAN_IR_Flags) || (0 == u32FreeLevel))
{
break;
}
}
/* Check that the Tx FIFO/Queue has an allocated area into the RAM */
if ((0 == (hfdcan->Instance->TXBC & FDCAN_TXBC_TFQS)) && (false == (*pErrorAbortTx)))
{
// if (0 == (hfdcan->Instance->IR & (FDCAN_ERROR_FLAGS))) // { /* Update error code / hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM; nStatus.hs = HAL_ERROR; assert_failed((uint8_t)FILE, LINE); // } // else // { // u32FDCAN_IR_Flags = poN_ErorsAndErrorStatuses->u32CurrentFDCAN_IR_Value; // } break; } /* Check that the Tx FIFO/Queue is not full */ if (((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U) && (false == (pErrorAbortTx))) { / Update error code / hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL; nStatus.hs = HAL_ERROR; break; } else if (false == (pErrorAbortTx)) { const uint8_t DLCtoBytes[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64 }; uint32_t TxElementW1; uint32_t TxElementW2; uint32_t TxAddress; uint32_t ByteCounter; if (0 == u32TotalMessagesAddedToFIFO) { / Retrieve the Tx FIFO PutIndex / u32CurrentPutIndex = ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos); } else { ++u32CurrentPutIndex; if (hfdcan->Init.TxFifoQueueElmtsNbr <= u32CurrentPutIndex) // u32CollatedPutIndexes) { u32CurrentPutIndex = 0; //u32CollatedPutIndexes = 0; } } / Add the message to the Tx FIFO/Queue / // Function FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, u32CurrentPutIndex) is of type static hence copyingits code below: { / Build first word of Tx header element / if (pTxHeader->IdType == FDCAN_STANDARD_ID) { TxElementW1 = (pTxHeader->ErrorStateIndicator | FDCAN_STANDARD_ID | pTxHeader->TxFrameType | (pTxHeader->Identifier << 18)); } else / pTxHeader->IdType == FDCAN_EXTENDED_ID */ { TxElementW1 = (pTxHeader->ErrorStateIndicator | FDCAN_EXTENDED_ID | pTxHeader->TxFrameType | pTxHeader->Identifier); }
/* Build second word of Tx header element */
TxElementW2 = ((pTxHeader->MessageMarker << 24) |
pTxHeader->TxEventFifoControl |
pTxHeader->FDFormat |
pTxHeader->BitRateSwitch |
pTxHeader->DataLength);
/* Calculate Tx element address */
TxAddress = (uint32_t*)(hfdcan->msgRam.TxBufferSA + (u32CurrentPutIndex * hfdcan->Init.TxElmtSize * 4U));
/* Write Tx element header to the message RAM */
*TxAddress = TxElementW1;
TxAddress++;
*TxAddress = TxElementW2;
TxAddress++;
/* Write Tx payload to the message RAM */
for (ByteCounter = 0; ByteCounter < DLCtoBytes[pTxHeader->DataLength >> 16]; ByteCounter += 4U)
{
*TxAddress = (((uint32_t)pTxData[ByteCounter + 3U] << 24) |
((uint32_t)pTxData[ByteCounter + 2U] << 16) |
((uint32_t)pTxData[ByteCounter + 1U] << 8) |
(uint32_t)pTxData[ByteCounter]);
TxAddress++;
}
// #DRA: moved down: pTxData += DLCtoBytes[pTxHeader->DataLength >> 16]; }
uint32_t u32BitPosition = ((uint32_t)1 << u32CurrentPutIndex);
// Check FDCAN Tx buffer request pending register for transmission pending for selected FIFO. // In Reference Manual of STM32H753, under FDCAN_TXFQS register details, it is informed that: // The Tx FIFO/queue status is related to the pending Tx requests listed in register // FDCAN_TXBRP. Therefore the effect of add/cancellation requests may be delayed due to a // running Tx scan (FDCAN_TXBRP not yet updated) // Hence, I feel we can safely use FDCAN_TXBRP to know if a FIFO is available for write. //ValueTXBRP = hfdcan->Instance->TXBRP; //if ((ValueTXBRP & u32BitPosition) && (false == (pErrorAbortTx))) //{ // assert_failed((uint8_t)FILE, LINE); //} //else if (true == (*pErrorAbortTx)) //{ // u32FDCAN_IR_Flags = poN_ErrorsAndErrorStatuses->u32CurrentFDCAN_IR_Value; // nStatus.cs = CANErrorOrErrorStatusTriggered; // return nStatus; // break; //}
/* Collate corresponding transmission request */
u32CollatedPutIndexes |= u32BitPosition;
/* Store the Latest Tx FIFO/Queue Request Buffer Index */
hfdcan->LatestTxFifoQRequest = u32BitPosition;
++u32TotalMessagesAddedToFIFO;
--u32NumberOfMessagesToAddToTxFIFO;
if (true == (*pErrorAbortTx))
{
break;
}
if (((u32TotalMessagesAddedToFIFO == u32FreeLevel) || (0 == u32NumberOfMessagesToAddToTxFIFO)) && (false == (*pErrorAbortTx)))
{
/* Activate the collated transmission requests */
hfdcan->Instance->TXBAR = u32CollatedPutIndexes;
if (0 == u32NumberOfMessagesToAddToTxFIFO)
{
nStatus.hs = HAL_OK;
break;
}
else
{
u32TotalMessagesAddedToFIFO = 0;
u32CollatedPutIndexes = 0;
u32FreeLevel = 0;
}
}
if (0 != u32NumberOfMessagesToAddToTxFIFO)
{
pTxData += DLCtoBytes[pTxHeader->DataLength >> 16];
// Point to next valid Header which is to be transmitted.
pTxHeader++;
}
}
}
}
else
{
/* Update error code */
hfdcan->ErrorCode |= HAL_FDCAN_ERROR_NOT_STARTED;
nStatus.hs = HAL_ERROR;
break;
}
} while (0);
}
if ((true == (*pErrorAbortTx)) || u32FDCAN_IR_Flags)
{
(*pErrorAbortTx) = true;
hfdcan->ErrorCode |= u32FDCAN_IR_Flags;
nStatus.cs = CANErrorOrErrorStatusTriggered;
}
return nStatus;
}
endif // of defined(dAddMultipleTxCANMessagesToFIFO)
// //- - - - - - - - rvCRC_Evans_FDCAN_ConfigFiler - - - - - - - // void rvCRC_Evans_FDCAN_ConfigFiler( uint8_t * const pu8MaxExtendedCANFilters, uint8_t * const pu8MaxStandardCANFilters, FDCAN_HandleTypeDef * const oThisFDCANHandleTypeDef /*!< Register base address */ ) { FDCAN_FilterTypeDef * pgNoClassicCANReceiveMessageFilters = NULL; uint32_t u32MaxCount = *(pu8MaxExtendedCANFilters) + *(pu8MaxStandardCANFilters);
// Converting 32 bit address to a 32 bit value and checking what must be executed.
// Switch cannot act upon addresses, it can however act on integer type values
switch((uint32_t)oThisFDCANHandleTypeDef->Instance)
{
default:
{
assert_failed((uint8_t *)__FILE__, __LINE__);
break;
}
if (1 == MX_FDCAN1)
case (uint32_t)(FDCAN1):
{
if(u32MaxCount > dUsedCAN1TxFIFOElmtsNbr)
{
dOutputConstantErrorMessage("\nRequired RX FIFO for CAN 1 is greater than usable RX FIFOs!");
dLEDShowError(dNoMoreCAN1_RX_FIFO_Available);
}
pgNoClassicCANReceiveMessageFilters = gNoClassicCAN1ReceiveMessageFilters;
break;
}
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
case (uint32_t)(FDCAN2):
{
if(u32MaxCount > dUsedCAN2TxFIFOElmtsNbr)
{
dOutputConstantErrorMessage("\nRequired RX FIFO for CAN 2 is greater than usable RX FIFOs!");
dLEDShowError(dNoMoreCAN2_RX_FIFO_Available);
}
pgNoClassicCANReceiveMessageFilters = gNoClassicCAN2ReceiveMessageFilters;
break;
}
endif // of (1 == MX_FDCAN2)
}
assert_param(NULL != pgNoClassicCANReceiveMessageFilters);
uint32_t u32Count = 0;
while(u32Count < u32MaxCount)
{
pgNoClassicCANReceiveMessageFilters->FilterIndex = u32Count;
if(HAL_OK != HAL_FDCAN_ConfigFilter((FDCAN_HandleTypeDef *)oThisFDCANHandleTypeDef, (FDCAN_FilterTypeDef *)pgNoClassicCANReceiveMessageFilters))
{
if (1 == MX_FDCAN1)
if(FDCAN1 == oThisFDCANHandleTypeDef->Instance)
{
dLEDShowError(dFDCAN1FilterConfigFail);
}
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
if(FDCAN2 == oThisFDCANHandleTypeDef->Instance)
{
dLEDShowError(dFDCAN2FilterConfigFail);
}
endif // of (1 == MX_FDCAN2)
assert_failed((uint8_t *)__FILE__, __LINE__);
}
++pgNoClassicCANReceiveMessageFilters;
++u32Count;
}
}
endif // of (1 == MX_FDCAN1) || (1 == MX_FDCAN2)
if (1 == MX_FDCAN1)
// Function helps declare CAN message filters and keep track of number of used // Standard and Extended CAN filters. // //- - - - - - - - rvCRC_Evans_AddCAN1MessagesFilters - - - - - - - // void rvCRC_Evans_AddCAN1MessagesFilters(void) { rvCRC_Evans_FDCAN_ConfigFiler(&u8MaxExtendedCAN1Filters, &u8MaxStandardCAN1Filters, &hfdcan1); }
// //- - - - - - - - rvCAN1_Initialize - - - - - - - // void rvCAN1_Initialize(void) {
if (1==DRA_USE_FDCAN1_AS_FDCAN)
// Transmit Delay Compensation Enabled. // Refer to section "55.3.1 Operating modes" part "Transceiver delay compensation" // for details HAL_FDCAN_EnableTxDelayCompensation(&hfdcan1);
// NOTES: // FDCAN_PSR.TDCV shows the actual transmitter delay compensation value, it is cleared // when FDCAN_CCCR.INIT is set and is updated at each transmission of an FD frame while // FDCAN_DBTP.TDC is set. // The following boundary conditions have to be considered for the transmitter delay // compensation implemented in the FDCAN: // The sum of the measured delay from m_ttcan_tx to m_ttcan_rx and the configured // transmitter delay compensation offset FDCAN_TDCR.TDCO has to be less than six bit // times in the data phase. // The sum of the measured delay from m_ttcan_tx to m_ttcan_rx and the configured // transmitter delay compensation offset FDCAN_TDCR.TDCO has to be less or equal // 127 mtq. In case this sum exceeds 127 mtq, the maximum value (127 mtq) is used for // transmitter delay compensation. // The data phase ends at the sample point of the CRC delimiter, that stops checking // received bits at the SSPs
endif
/* Activating various Interrupts : START */
///** @defgroup FDCAN_Tx_Interrupts FDCAN Tx Interrupts //#DRA: Added to Interrupt requests: #define FDCAN_IT_TX_COMPLETE FDCAN_IE_TCE /*!< Transmission Completed / //#define FDCAN_IT_TX_ABORT_COMPLETE FDCAN_IE_TCFE /!< Transmission Cancellation Finished / //#DRA: Added to Interrupt requests: #define FDCAN_IT_TX_FIFO_EMPTY FDCAN_IE_TFEE /!< Tx FIFO Empty */
///** @defgroup FDCAN_Counter_Interrupts FDCAN Counter Interrupts //#define FDCAN_IT_TIMESTAMP_WRAPAROUND FDCAN_IE_TSWE /*!< Timestamp counter wrapped around / //#define FDCAN_IT_TIMEOUT_OCCURRED FDCAN_IE_TOOE /!< Timeout reached */
//HAL_StatusTypeDef HAL_FDCAN_ConfigTimestampCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimestampPrescaler); //HAL_StatusTypeDef HAL_FDCAN_ConfigTimeoutCounter(FDCAN_HandleTypeDef *hfdcan, uint32_t TimeoutOperation, uint32_t TimeoutPeriod);
///** @defgroup FDCAN_Clock_Calibration_Interrupts Clock Calibration Interrupts //#define FDCAN_IT_CALIB_STATE_CHANGED (FDCANCCU_IE_CSCE << 30) /*!< Clock calibration state changed / //#define FDCAN_IT_CALIB_WATCHDOG_EVENT (FDCANCCU_IE_CWEE << 30) /!< Clock calibration watchdog event occurred */
//HAL_StatusTypeDef HAL_FDCAN_ConfigClockCalibration(FDCAN_HandleTypeDef *hfdcan, FDCAN_ClkCalUnitTypeDef *sCcuConfig);
///** @defgroup FDCAN_Error_Interrupts FDCAN Error Interrupts //#DRA: Added to Interrupt requests: #define FDCAN_IT_RAM_ACCESS_FAILURE FDCAN_IE_MRAFE /*!< Message RAM access failure occurred / //#DRA: Added to Interrupt requests: #define FDCAN_IT_ERROR_LOGGING_OVERFLOW FDCAN_IE_ELOE /!< Overflow of FDCAN Error Logging Counter occurred / //#DRA: Added to Interrupt requests: #define FDCAN_IT_RAM_WATCHDOG FDCAN_IE_WDIE /!< Message RAM Watchdog event due to missing READY / //#DRA: Added to Interrupt requests: #define FDCAN_IT_ARB_PROTOCOL_ERROR FDCAN_IE_PEAE /!< Protocol error in arbitration phase detected / //#DRA: Added to Interrupt requests: #define FDCAN_IT_DATA_PROTOCOL_ERROR FDCAN_IE_PEDE /!< Protocol error in data phase detected / //#DRA: Added to Interrupt requests: #define FDCAN_IT_RESERVED_ADDRESS_ACCESS FDCAN_IE_ARAE /!< Access to reserved address occurred */
//HAL_StatusTypeDef HAL_FDCAN_ConfigRamWatchdog(FDCAN_HandleTypeDef *hfdcan, uint32_t CounterStartValue); //HAL_StatusTypeDef HAL_FDCAN_ConfigExtendedIdMask(FDCAN_HandleTypeDef *hfdcan, uint32_t Mask); //HAL_StatusTypeDef HAL_FDCAN_ConfigTxDelayCompensation(FDCAN_HandleTypeDef *hfdcan, uint32_t TdcOffset, uint32_t TdcFilter); //HAL_StatusTypeDef HAL_FDCAN_ConfigInterruptLines(FDCAN_HandleTypeDef *hfdcan, uint32_t ITList, uint32_t InterruptLine);
if 0
/* Activate various FDCAN_Rx_Interrupts notifications. */
HAL_FDCAN_ActivateNotification( &hfdcan1
, FDCAN_IT_RX_HIGH_PRIORITY_MSG /*!< High priority message received */
| FDCAN_IT_RX_BUFFER_NEW_MESSAGE /*!< At least one received message stored into a Rx Buffer */
, 0);
endif // of 0
/* Activate various FDCAN_Error_Interrupts notifications. */
HAL_FDCAN_ActivateNotification( &hfdcan1
, 0
// | FDCAN_IT_RAM_ACCESS_FAILURE /*!< Message RAM access failure occurred / // | FDCAN_IT_ERROR_LOGGING_OVERFLOW /!< Overflow of FDCAN Error Logging Counter occurred / // | FDCAN_IT_RAM_WATCHDOG /!< Message RAM Watchdog event due to missing READY / // | FDCAN_IT_RESERVED_ADDRESS_ACCESS /!< Access to reserved address occurred */ , 0);
// NOTES: // // The Bus_Off recovery sequence (see CAN Specification Rev. 2.0 or ISO11898-1) cannot be // shortened by setting or resetting FDCAN_CCCR.INIT. If the device goes Bus_Off, it will set // FDCAN_CCCR.INIT of its own, stopping all bus activities. Once FDCAN_CCCR.INIT has // been cleared by the CPU, the device will then wait for 129 occurrences of bus Idle (129 × 11 // consecutive recessive bits) before resuming normal operation. At the end of the Bus_Off // recovery sequence, the error management counters will be reset. During the waiting time // after the reset of FDCAN_CCCR.INIT, each time a sequence of 11 recessive bits has been // monitored, a Bit0 error code is written to FDCAN_PSR.LEC, enabling the CPU to readily // check up whether the CAN bus is stuck at dominant or continuously disturbed and to // monitor the Bus_Off recovery sequence. FDCAN_ECR.REC is used to count these // sequences.
/* Activate various FDCAN_Error_Status_Interrupts notifications. */
HAL_FDCAN_ActivateNotification( &hfdcan1
, 0
| FDCAN_IT_ERROR_WARNING /*!< Error_Warning status changed */
// #DRA: These interrupts are Polled for, when Error Warning is triggered. // | FDCAN_IT_BUS_OFF /*!< Bus_Off status changed / | FDCAN_IT_ERROR_PASSIVE /!< Error_Passive status changed / // | FDCAN_IT_ARB_PROTOCOL_ERROR /!< Protocol error in arbitration phase detected / // | FDCAN_IT_DATA_PROTOCOL_ERROR /!< Protocol error in data phase detected */ , 0);
/* Activating various Interrupts : END */
/* Tx FIFO related implementations : START */
if 0
if (dCAN1TxFIFOElmtsLeftToFull < dUsedCAN1TxFIFOElmtsNbr) && defined(DRA_USE_CAN1_TX_WATER_MARK_INTERRUPT)
/* Configure Tx FIFO watermark */
HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_TX_EVENT_FIFO, (dUsedCAN1TxFIFOElmtsNbr - dCAN1TxFIFOElmtsLeftToFull));
endif // of (dCAN1TxFIFOElmtsLeftToFull < dUsedCAN1TxFIFOElmtsNbr) && defined(DRA_USE_CAN1_TX_WATER_MARK_INTERRUPT)
endif // of 0/1
if (0 < dUsedCAN1TxFIFOElmtsNbr)
// NOTES: // // To support Tx event handling the FDCAN has implemented a Tx event FIFO. After the // FDCAN has transmitted a message on the CAN bus, message ID and timestamp are stored // in a Tx event FIFO element. To link a Tx event to a Tx event FIFO element, the message // marker from the transmitted Tx buffer is copied into the Tx event FIFO element. // The Tx event FIFO can be configured to a maximum of 32 elements. The Tx event FIFO // element is described in Tx FIFO. Depending on the configuration of the element size // (FDCAN_TXESC), between two and sixteen 32-bit words (Tn = 3 ..17) are used for storage // of a CAN message data field. // // When a Tx event FIFO full condition is signaled by FDCAN_IR.TEFF, no further elements // are written to the Tx event FIFO until at least one element has been read out and the Tx // event FIFO get index has been incremented. In case a Tx event occurs while the Tx event // FIFO is full, this event is discarded and interrupt flag FDCAN_IR.TEFL is set. // // To avoid a Tx event FIFO overflow, the Tx event FIFO watermark can be used. When the Tx // event FIFO fill level reaches the Tx event FIFO watermark configured by // FDCAN_TXEFC.EFWM, interrupt flag FDCAN_IR.TEFW is set. // When reading from the Tx event FIFO, two times the Tx event FIFO get index // FDCAN_TXEFS.EFGI has to be added to the Tx event FIFO start address // FDCAN_TXEFC.EFSA.
// IMPORTANT NOTE: // // NONE OF THE BELOW TX INTERRUPTS are used // // FDCAN_IT_TX_EVT_FIFO_FULL /*!< Tx Event FIFO full / // FDCAN_IT_TX_EVT_FIFO_WATERMARK /!< Tx Event FIFO fill level reached watermark / // FDCAN_IT_TX_EVT_FIFO_NEW_DATA /!< Tx Handler wrote Tx Event FIFO element / // FDCAN_IT_TX_FIFO_EMPTY /!< Tx FIFO Empty */ // // This is because when sending out multiple CAN MEssages, it takes a while for the interrupts to Trigger. // The TX FIFO alreadys gets full before any interrupt gets triggered, and hence at least one CAN TX // message gets lost. // // It is rather beneficial to first check for TX FIFO Full (related register) before starting to add // any data, and then use HAL_FDCAN_GetTxFifoFreeLevel() to know how many more buffers are available.
/* Activate various FDCAN_Tx_Event_Fifo_Interrupt notifications */
HAL_FDCAN_ActivateNotification(&hfdcan1
, 0
| FDCAN_IT_TX_FIFO_EMPTY /*!< Tx FIFO Empty */
//# if (0 < dUseCAN1TxEventsNbr) // | FDCAN_IT_TX_EVT_FIFO_ELT_LOST /*!< Tx Event FIFO element lost / // | FDCAN_IT_TX_EVT_FIFO_NEW_DATA //# endif // of (0 < dUseCAN1TxEventsNbr) // | FDCAN_IT_TX_EVT_FIFO_FULL // | FDCAN_IT_TX_COMPLETE /!< Transmission Completed */ , 0); //~((-1UL) << dUseCAN1TxEventsNbr));
endif // of (0 < dUsedCAN1TxFIFOElmtsNbr)
/* Tx FIFO related implementations : END */
/* Configure global filter to reject all non-matching frames */ if(HAL_OK != HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, dCAN1NonMatchingStd, dCAN1NonMatchingExt, dCAN1RejectRemoteStd, dCAN1RejectRemoteExt)) { dLEDShowError(dFDCAN1GlobalFilterConfigFail); assert_failed((uint8_t *)FILE, LINE); }
if ( dNoUnknownCANMessageAccepted & dUsedCAN1RxFIFOConfiguration )
rvCRC_Evans_AddCAN1MessagesFilters();
endif // of ( dNoUnknownCANMessageAccepted & dUsedCAN1RxFIFOConfiguration )
/* Rx FIFO 0 related implementations : START */
if ( ( dFIFO0AcceptsUnknownCANMessages | dFIFO0ReceivesFilteredCANMessages) & ( dUsedCAN1RxFIFOConfiguration ) )
/* Configure Rx FIFO 0 Blocking or Overwrite. */
HAL_FDCAN_ConfigRxFifoOverwrite(&hfdcan1
, FDCAN_RX_FIFO0
if defined(dCAN1RxFIFO0InBlockingMode)
, FDCAN_RX_FIFO_BLOCKING
elif defined(dCAN1RxFIFO0InOverwriteMode)
, FDCAN_RX_FIFO_OVERWRITE
endif // of defined(dCAN1RxFIFO0InBlockingMode)
);
endif // of ( ( dFIFO0AcceptsUnknownCANMessages | dFIFO0ReceivesFilteredCANMessages) & ( dUsedCAN1RxFIFOConfiguration ) )
if (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO0ElmtsNbr) && defined(DRA_USE_CAN1_RX_WATER_MARK_INTERRUPT)
/* Configure Rx FIFO 0 watermark */
HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO0, (dUsedCAN1RxFIFO0ElmtsNbr - dCAN1RxFIFOElmtsLeftToFull));
/* Activate Rx FIFO 0 watermark notification */
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_WATERMARK, 0);
endif // of (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO0ElmtsNbr) && defined(DRA_USE_CAN1_RX_WATER_MARK_INTERRUPT)
if (0 < dUsedCAN1RxFIFO0ElmtsNbr)
/* Activate various FDCAN_Rx_Fifo0_Interrupts notifications */
if(HAL_OK !=
HAL_FDCAN_ActivateNotification( &hfdcan1
, 0
| FDCAN_IT_RX_FIFO0_FULL /*!< Rx FIFO 0 full */
| FDCAN_IT_RX_FIFO0_NEW_MESSAGE /*!< New message written to Rx FIFO 0 */
if defined(dCAN1RxFIFO0InBlockingMode)
| FDCAN_IT_RX_FIFO0_MESSAGE_LOST /*!< Rx FIFO 0 message lost */
endif // of defined(dCAN1RxFIFO0InBlockingMode)
if (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO0ElmtsNbr)
| FDCAN_IT_RX_FIFO0_WATERMARK /*!< Rx FIFO 0 fill level reached watermark */
endif // of (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO0ElmtsNbr)
, 0)
)
{
dLEDShowError(dFDCAN1ActivateNotificationFail);
assert_failed((uint8_t *)__FILE__, __LINE__);
}
endif // of (0 < dUsedCAN1RxFIFO0ElmtsNbr)
/* Rx FIFO 0 related implementations : END */
/* Rx FIFO 1 related implementations : START */
if ( ( dFIFO1AcceptsUnknownCANMessages | dFIFO1ReceivesFilteredCANMessages) & ( dUsedCAN1RxFIFOConfiguration ) )
/* Configure Rx FIFO 1 Blocking or Overwrite. */
HAL_FDCAN_ConfigRxFifoOverwrite(&hfdcan1
, FDCAN_RX_FIFO1
if defined(dCAN1RxFIFO1InBlockingMode)
, FDCAN_RX_FIFO_BLOCKING
elif defined(dCAN1RxFIFO1InOverwriteMode)
, FDCAN_RX_FIFO_OVERWRITE
endif // of defined(dCAN1RxFIFO1InBlockingMode)
);
endif // of ( ( dFIFO1AcceptsUnknownCANMessages | dFIFO1ReceivesFilteredCANMessages) & ( dUsedCAN1RxFIFOConfiguration ) )
if (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO1ElmtsNbr) && defined(DRA_USE_CAN1_RX_WATER_MARK_INTERRUPT)
/* Configure Rx FIFO 1 watermark */
HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO1, (dUsedCAN1RxFIFO1ElmtsNbr - dCAN1RxFIFOElmtsLeftToFull));
/* Activate Rx FIFO 0 watermark notification */
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO1_WATERMARK, 0);
endif // of (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO1ElmtsNbr) && defined(DRA_USE_CAN1_RX_WATER_MARK_INTERRUPT)
if (0 < dUsedCAN1RxFIFO1ElmtsNbr)
/* Activate various DCAN_RX_FIFO1_Interrupts notifications */
if(HAL_OK !=
HAL_FDCAN_ActivateNotification( &hfdcan1
, 0
| FDCAN_IT_RX_FIFO1_FULL /*!< Rx FIFO 0 full */
| FDCAN_IT_RX_FIFO1_NEW_MESSAGE /*!< New message written to Rx FIFO 1 */
if defined(dRxFIFO1InBlockingMode)
| FDCAN_IT_RX_FIFO1_MESSAGE_LOST /*!< Rx FIFO 0 message lost */
endif // of dRxFIFO0InBlockingMode
if (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO1ElmtsNbr)
| FDCAN_IT_RX_FIFO1_WATERMARK /*!< Rx FIFO 1 fill level reached watermark */
endif // of (dCAN1RxFIFOElmtsLeftToFull < dUsedCAN1RxFIFO1ElmtsNbr)
, 0)
)
{
dLEDShowError(dFDCAN1ActivateNotificationFail);
assert_failed((uint8_t *)__FILE__, __LINE__);
}
endif // of (0 < dUsedCAN1RxFIFO1ElmtsNbr)
/* Rx FIFO 1 related implementations : END */
if(HAL_OK != HAL_FDCAN_Start(&hfdcan1))
{
dLEDShowError(dFDCAN1ModuleStartFail);
assert_failed((uint8_t *)__FILE__, __LINE__);
}
}
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
// Function helps declare CAN message filters and keep track of number of used // Standard and Extended CAN filters. // //- - - - - - - - rvCRC_Evans_AddCAN2MessagesFilters - - - - - - - // void rvCRC_Evans_AddCAN2MessagesFilters(void) { rvCRC_Evans_FDCAN_ConfigFiler(&u8MaxExtendedCAN2Filters, &u8MaxStandardCAN2Filters, &hfdcan2); }
// //- - - - - - - - rvCAN2_Initialize - - - - - - - // void rvCAN2_Initialize(void) { /* Activating various Interrupts : START */
/* Activate various FDCAN_Error_Interrupts notifications. */
HAL_FDCAN_ActivateNotification( &hfdcan2
, 0
// | FDCAN_IT_RAM_ACCESS_FAILURE /*!< Message RAM access failure occurred / // | FDCAN_IT_ERROR_LOGGING_OVERFLOW /!< Overflow of FDCAN Error Logging Counter occurred / // | FDCAN_IT_RAM_WATCHDOG /!< Message RAM Watchdog event due to missing READY / // | FDCAN_IT_RESERVED_ADDRESS_ACCESS /!< Access to reserved address occurred */ , 0);
/* Activate various FDCAN_Error_Status_Interrupts notifications. */
HAL_FDCAN_ActivateNotification( &hfdcan2
, 0
| FDCAN_IT_ERROR_WARNING /*!< Error_Warning status changed */
// #DRA: These interrupts are Polled for, when Error Warning is triggered. // | FDCAN_IT_BUS_OFF /*!< Bus_Off status changed / | FDCAN_IT_ERROR_PASSIVE /!< Error_Passive status changed / // | FDCAN_IT_ARB_PROTOCOL_ERROR /!< Protocol error in arbitration phase detected / // | FDCAN_IT_DATA_PROTOCOL_ERROR /!< Protocol error in data phase detected */ , 0);
/* Activating various Interrupts : END */
/* Tx FIFO related implementations : START */
if (0 < dUsedCAN2TxFIFOElmtsNbr)
/* Activate various FDCAN_Tx_Event_Fifo_Interrupt notifications */
HAL_FDCAN_ActivateNotification(&hfdcan2
, 0
| FDCAN_IT_TX_FIFO_EMPTY /*!< Tx FIFO Empty */
//# if (0 < dUseCAN2TxEventsNbr) // | FDCAN_IT_TX_EVT_FIFO_ELT_LOST /*!< Tx Event FIFO element lost / // | FDCAN_IT_TX_EVT_FIFO_NEW_DATA //# endif // of (0 < dUseCAN2TxEventsNbr) // | FDCAN_IT_TX_EVT_FIFO_FULL // | FDCAN_IT_TX_COMPLETE /!< Transmission Completed */ , 0); //~((-1UL) << dUseCAN2TxEventsNbr));
endif // of (0 < dUsedCAN2TxFIFO0ElmtsNbr)
/* Tx FIFO related implementations : END */
/* Configure global filter to reject all non-matching frames */
if(HAL_OK != HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, dCAN2NonMatchingStd, dCAN2NonMatchingExt, dCAN2RejectRemoteStd, dCAN2RejectRemoteExt))
{
dLEDShowError(dFDCAN2GlobalFilterConfigFail);
assert_failed((uint8_t *)__FILE__, __LINE__);
}
if ( dNoUnknownCANMessageAccepted & dUsedCAN2RxFIFOConfiguration )
rvCRC_Evans_AddCAN2MessagesFilters();
endif // of ( dNoUnknownCANMessageAccepted & dUsedCAN2RxFIFOConfiguration )
/* Rx FIFO 0 related implementations : START */
if ( ( dFIFO0AcceptsUnknownCANMessages | dFIFO0ReceivesFilteredCANMessages) & ( dUsedCAN2RxFIFOConfiguration ) )
/* Configure Rx FIFO 0 Blocking or Overwrite. */
HAL_FDCAN_ConfigRxFifoOverwrite(&hfdcan2
, FDCAN_RX_FIFO0
if defined(dCAN2RxFIFO0InBlockingMode)
, FDCAN_RX_FIFO_BLOCKING
elif defined(dCAN2RxFIFO0InOverwriteMode)
, FDCAN_RX_FIFO_OVERWRITE
endif // of defined(dCAN2RxFIFO0InBlockingMode)
);
endif // of ( ( dFIFO0AcceptsUnknownCANMessages | dFIFO0ReceivesFilteredCANMessages) & ( dUsedCAN2RxFIFOConfiguration ) )
if (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO0ElmtsNbr) && defined(DRA_USE_CAN2_RX_WATER_MARK_INTERRUPT)
/* Configure Rx FIFO 0 watermark */
HAL_FDCAN_ConfigFifoWatermark(&hfdcan2, FDCAN_CFG_RX_FIFO0, (dUsedCAN2RxFIFO0ElmtsNbr - dCAN2RxFIFOElmtsLeftToFull));
/* Activate Rx FIFO 0 watermark notification */
HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_WATERMARK, 0);
endif // of (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO0ElmtsNbr) && defined(DRA_USE_CAN2_RX_WATER_MARK_INTERRUPT)
if (0 < dUsedCAN2RxFIFO0ElmtsNbr)
/* Activate various FDCAN_Rx_Fifo0_Interrupts notifications */
if(HAL_OK !=
HAL_FDCAN_ActivateNotification( &hfdcan2
, 0
| FDCAN_IT_RX_FIFO0_FULL /*!< Rx FIFO 0 full */
| FDCAN_IT_RX_FIFO0_NEW_MESSAGE /*!< New message written to Rx FIFO 0 */
if defined(dCAN2RxFIFO0InBlockingMode)
| FDCAN_IT_RX_FIFO0_MESSAGE_LOST /*!< Rx FIFO 0 message lost */
endif // of defined(dCAN2RxFIFO0InBlockingMode)
if (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO0ElmtsNbr)
| FDCAN_IT_RX_FIFO0_WATERMARK /*!< Rx FIFO 0 fill level reached watermark */
endif // of (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO0ElmtsNbr)
, 0)
)
{
dLEDShowError(dFDCAN2ActivateNotificationFail);
assert_failed((uint8_t *)__FILE__, __LINE__);
}
endif // of (0 < dUsedCAN2RxFIFO0ElmtsNbr)
/* Rx FIFO 0 related implementations : END */
/* Rx FIFO 1 related implementations : START */
if ( ( dFIFO1AcceptsUnknownCANMessages | dFIFO1ReceivesFilteredCANMessages) & ( dUsedCAN2RxFIFOConfiguration ) )
/* Configure Rx FIFO 1 Blocking or Overwrite. */
HAL_FDCAN_ConfigRxFifoOverwrite(&hfdcan2
, FDCAN_RX_FIFO1
if defined(dCAN2RxFIFO1InBlockingMode)
, FDCAN_RX_FIFO_BLOCKING
elif defined(dCAN2RxFIFO1InOverwriteMode)
, FDCAN_RX_FIFO_OVERWRITE
endif // of defined(dCAN2RxFIFO1InBlockingMode)
);
endif // of ( ( dFIFO1AcceptsUnknownCANMessages | dFIFO1ReceivesFilteredCANMessages) & ( dUsedCAN2RxFIFOConfiguration ) )
if (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO1ElmtsNbr) && defined(DRA_USE_CAN2_RX_WATER_MARK_INTERRUPT)
/* Configure Rx FIFO 1 watermark */
HAL_FDCAN_ConfigFifoWatermark(&hfdcan2, FDCAN_CFG_RX_FIFO1, (dUsedCAN2RxFIFO1ElmtsNbr - dCAN2RxFIFOElmtsLeftToFull));
/* Activate Rx FIFO 0 watermark notification */
HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO1_WATERMARK, 0);
endif // of (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO1ElmtsNbr) && defined(DRA_USE_CAN2_RX_WATER_MARK_INTERRUPT)
if (0 < dUsedCAN2RxFIFO1ElmtsNbr)
/* Activate various DCAN_RX_FIFO1_Interrupts notifications */
if(HAL_OK !=
HAL_FDCAN_ActivateNotification( &hfdcan2
, 0
| FDCAN_IT_RX_FIFO1_FULL /*!< Rx FIFO 0 full */
| FDCAN_IT_RX_FIFO1_NEW_MESSAGE /*!< New message written to Rx FIFO 1 */
if defined(dRxFIFO1InBlockingMode)
| FDCAN_IT_RX_FIFO1_MESSAGE_LOST /*!< Rx FIFO 0 message lost */
endif // of dRxFIFO0InBlockingMode
if (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO1ElmtsNbr)
| FDCAN_IT_RX_FIFO1_WATERMARK /*!< Rx FIFO 1 fill level reached watermark */
endif // of (dCAN2RxFIFOElmtsLeftToFull < dUsedCAN2RxFIFO1ElmtsNbr)
, 0)
)
{
dLEDShowError(dFDCAN2ActivateNotificationFail);
assert_failed((uint8_t *)__FILE__, __LINE__);
}
endif // of (0 < dUsedCAN2RxFIFO1ElmtsNbr)
/* Rx FIFO 1 related implementations : END */
if(HAL_OK != HAL_FDCAN_Start(&hfdcan2))
{
dLEDShowError(dFDCAN2ModuleStartFail);
assert_failed((uint8_t *)__FILE__, __LINE__);
}
}
endif // of (1 == MX_FDCAN2)
if ( 1 == MX_FDCAN1 ) || ( 1 == MX_FDCAN2 )
// //- - - - - - - - rvCRC_Evans_CalculateNeededFilters - - - - - - - // void rvCRC_Evans_CalculateNeededFilters( uint8_t * const pu8MaxExtendedCANFilters, uint8_t * const pu8MaxStandardCANFilters, FDCAN_GlobalTypeDef * const ThisFDCANInstance /*!< Register base address */ ) { const FDCAN_FilterTypeDef * pgNoClassicCANReceiveMessageFilters = NULL;
uint32_t u32Count;
uint32_t u32MaxCount;
*(pu8MaxExtendedCANFilters) = 0;
*(pu8MaxStandardCANFilters) = 0;
u32Count = 0;
// Converting 32 bit address to a 32 bit value and checking what must be executed.
// Switch cannot act upon addresses, it can however act on integer type values
switch((uint32_t)ThisFDCANInstance)
{
default:
{
assert_failed((uint8_t *)__FILE__, __LINE__);
break;
}
if ( 1 == MX_FDCAN1 )
case (uint32_t)(FDCAN1):
{
u32MaxCount = (sizeof(gNoClassicCAN1ReceiveMessageFilters) / sizeof(FDCAN_FilterTypeDef));
pgNoClassicCANReceiveMessageFilters = gNoClassicCAN1ReceiveMessageFilters;
break;
}
endif // of ( 1 == MX_FDCAN1 )
if ( 1 == MX_FDCAN2 )
case (uint32_t)(FDCAN2):
{
u32MaxCount = (sizeof(gNoClassicCAN2ReceiveMessageFilters) / sizeof(FDCAN_FilterTypeDef));
pgNoClassicCANReceiveMessageFilters = gNoClassicCAN2ReceiveMessageFilters;
break;
}
endif // of ( 1 == MX_FDCAN2 )
}
assert_param(NULL != pgNoClassicCANReceiveMessageFilters);
assert_param(dMaxAllowedCANRxFilters >= u32MaxCount);
while(u32Count < u32MaxCount)
{
if(FDCAN_EXTENDED_ID == (pgNoClassicCANReceiveMessageFilters)->IdType)
{
++(*pu8MaxExtendedCANFilters);
}
else if(FDCAN_EXTENDED_ID == (pgNoClassicCANReceiveMessageFilters)->IdType)
{
++(*pu8MaxStandardCANFilters);
}
else
{
assert_param(false);
}
++pgNoClassicCANReceiveMessageFilters;
++u32Count;
}
}
// //- - - - - - - - rvCRC_Evans_UpdateNeededRxFiltesrCounts - - - - - - - // void rvCRC_Evans_UpdateNeededRxFiltesrCounts(void) { // Code for finding needed Standard and Extended flters count for FDCAN1 / Classic CAN1
if ( 1 == MX_FDCAN1 )
rvCRC_Evans_CalculateNeededFilters(&u8MaxExtendedCAN1Filters, &u8MaxStandardCAN1Filters, FDCAN1);
if (0 != ((dFIFO0AcceptsUnknownCANMessages | dFIFO1AcceptsUnknownCANMessages) & dUsedCAN1RxFIFOConfiguration))
u8MaxExtendedCAN1Filters++;
endif // of (0 != ((dFIFO0AcceptsUnknownCANMessages | dFIFO1AcceptsUnknownCANMessages) & dUsedCAN1RxFIFOConfiguration))
assert_param(IS_FDCAN_MAX_VALUE(u8MaxStandardCAN1Filters, dMaxStandardCANFilters));
assert_param(IS_FDCAN_MAX_VALUE(u8MaxExtendedCAN1Filters, dMaxExtendedCANFilters));
endif // of ( 1 == MX_FDCAN1 )
// Code for finding needed Standard and Extended flters count for FDCANs / Classic CAN2
if ( 1 == MX_FDCAN2 )
rvCRC_Evans_CalculateNeededFilters(&u8MaxExtendedCAN2Filters, &u8MaxStandardCAN2Filters, FDCAN2);
if (0 != ((dFIFO0AcceptsUnknownCANMessages | dFIFO1AcceptsUnknownCANMessages) & dUsedCAN2RxFIFOConfiguration))
u8MaxExtendedCAN2Filters++;
endif // of (0 != ((dFIFO0AcceptsUnknownCANMessages | dFIFO1AcceptsUnknownCANMessages) & dUsedCAN2RxFIFOConfiguration))
assert_param(IS_FDCAN_MAX_VALUE(u8MaxStandardCAN2Filters, 128U));
assert_param(IS_FDCAN_MAX_VALUE(u8MaxExtendedCAN2Filters, 64U));
endif // of ( 1 == MX_FDCAN2 )
}
// //- - - - - - - - HAL_FDCAN_RxFifo1Callback - - - - - - - // void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs) { FDCAN_TxEventFifoTypeDef * poTxTxEventFifoType = NULL;
if ( 1 == MX_FDCAN1 )
if(FDCAN1 == hfdcan->Instance)
{
CapturedCAN1TxEventFIFOITs = TxEventFifoITs;
if(FDCAN_IT_TX_EVT_FIFO_WATERMARK == TxEventFifoITs)
{
if(!bCAN1WaterMarkReached)
{
bCAN1WaterMarkReached = true;
}
else
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
}
poTxTxEventFifoType = CheckCAN1TxEvtFIFO;
}
endif // of ( 1 == MX_FDCAN1 )
if ( 1 == MX_FDCAN2 )
if(FDCAN2 == hfdcan->Instance)
{
CapturedCAN2TxEventFIFOITs = TxEventFifoITs;
poTxTxEventFifoType = CheckCAN2TxEvtFIFO;
}
uint32_t u32MaxCount = hfdcan->Instance->TXEFS & FDCAN_TXEFS_EFFL;
uint32_t u32CurrentCount = 0;
while( u32CurrentCount < u32MaxCount)
{
HAL_FDCAN_GetTxEvent(hfdcan, ( poTxTxEventFifoType + u32CurrentCount ) );
u32CurrentCount++;
}
endif // of ( 1 == MX_FDCAN2 )
}
// //- - - - - - - - rvReadErrorsAndErrorStatuses - - - - - - - // void rvReadErrorsAndErrorStatuses(FDCAN_HandleTypeDef *hfdcan, struct _oN_ErrorsAndErrorStatuses * poN_ErrorsAndErrorStatuses) { FDCAN_ProtocolStatusTypeDef oN_ProtocolStatus; FDCAN_ErrorCountersTypeDef oN_ErrorCounters;
if 1
if( ( __BUGGY_1_STM32H7xx_HAL_VERSION <= HAL_GetHalVersion() ) && ( __BUGGY_2_STM32H7xx_HAL_VERSION >= HAL_GetHalVersion() ) )
{
uint32_t CountersReg;
/* Read the error counters register */
CountersReg = READ_REG(hfdcan->Instance->ECR);
/* Fill the error counters structure */
oN_ErrorCounters.TxErrorCnt = ((CountersReg & FDCAN_ECR_TEC) >> FDCAN_ECR_TEC_Pos);
oN_ErrorCounters.RxErrorCnt = ((CountersReg & FDCAN_ECR_REC) >> FDCAN_ECR_REC_Pos);
oN_ErrorCounters.RxErrorPassive = ((CountersReg & FDCAN_ECR_RP) >> FDCAN_ECR_RP_Pos);
oN_ErrorCounters.ErrorLogging = ((CountersReg & FDCAN_ECR_CEL) >> FDCAN_ECR_CEL_Pos);
}
else
{
dOutputConstantErrorMessage("\nCheck whether FDCAN_ECR_TEC value is changed to (0xFFUL << FDCAN_ECR_TEC_Pos). If not then modify the conditional check so that thie error is not reached.");
dLEDShowError(dHALDriverBug);
}
else // of 1/0
if(HAL_OK != HAL_FDCAN_GetErrorCounters(hfdcan, &oN_ErrorCounters))
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
endif // of 1/0
if(HAL_OK != HAL_FDCAN_GetProtocolStatus(hfdcan, &oN_ProtocolStatus))
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
else
{
if ( ( __BUGGY_1_STM32H7xx_HAL_VERSION <= __STM32H7xx_CURRENT_CMSIS_DEVICE_VERSION ) && ( __BUGGY_2_STM32H7xx_HAL_VERSION >= __STM32H7xx_CURRENT_CMSIS_DEVICE_VERSION ) )
// Note: FDCAN_COM_STATE macros like FDCAN_COM_STATE_TX should be shifted right by FDCAN_PSR_ACT_Pos before use.
// This file has redefined the FD_COM_STATE macros so as to have a value between 0 through 3 which matches with datasheet values.
//
oN_ProtocolStatus.Activity >>= FDCAN_PSR_ACT_Pos;
else // of ( ( __BUGGY_1_STM32H7xx_HAL_VERSION == __STM32H7xx_CURRENT_CMSIS_DEVICE_VERSION ) || ( __BUGGY_2_STM32H7xx_HAL_VERSION == __STM32H7xx_CURRENT_CMSIS_DEVICE_VERSION ) )
#warning STM32CubeH7 developers are not ready to right shift the variable StatusReg's value by FDCAN_PSR_ACT_Pos and then assign the result to ProtocolStatus->Activity.
#warning STM32CubeH7 developers are also not ready to change FDCAN_COM_STATE_XXX macros so as to have values in the range of 0 to 3. Refer https://github.com/STMicroelectronics/STM32CubeH7/issues/62
#error In function HAL_FDCAN_GetProtocolStatus(), check the value being assigned to ProtocolStatus->Activity. If assigned value is not right shift by FDCAN_PSR_ACT_Pos before assignment, then update the consitinal check that uses __BUGGY_x_STM32H7xx_HAL_VERSION, so as to resolve this error.
endif // of ( ( __BUGGY_1_STM32H7xx_HAL_VERSION == __STM32H7xx_CURRENT_CMSIS_DEVICE_VERSION ) || ( __BUGGY_2_STM32H7xx_HAL_VERSION == __STM32H7xx_CURRENT_CMSIS_DEVICE_VERSION ) )
}
poN_ErrorsAndErrorStatuses->oN_CurrentErrorCounters = oN_ErrorCounters;
poN_ErrorsAndErrorStatuses->oN_CurrentProtocolStatus = oN_ProtocolStatus;
}
// //- - - - - - - - HAL_FDCAN_TxFifoEmptyCallback - - - - - - - // void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan) {
if ( 1 == MX_FDCAN1 )
if(FDCAN1 == hfdcan->Instance)
{
if(true == bCAN1ErrorAbortTx)
{
bCAN1ErrorAbortTx = false;
}
}
else
endif // of ( 1 == MX_FDCAN1 )
if ( 1 == MX_FDCAN2 )
if(FDCAN2 == hfdcan->Instance)
{
if(true == bCAN2ErrorAbortTx)
{
bCAN2ErrorAbortTx = false;
}
}
else
endif // of ( 1 == MX_FDCAN2 )
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
}
// //- - - - - - - - rvCRC_Evans_Read_Errors_And_ErrorStatuses - - - - - - - // void rvCRC_Evans_Read_Errors_And_ErrorStatuses(FDCAN_HandleTypeDef *hfdcan, struct _oN_ErrorsAndErrorStatuses * poN_ErrorsAndErrorStatuses) { uint32_t u32IR = hfdcan->Instance->IR;
if( ( FDCAN_ERROR_STATUS_FLAGS | FDCAN_ERROR_FLAGS ) & u32IR )
{
if ( 1 == MX_FDCAN1 )
if(FDCAN1 == hfdcan->Instance)
{
bCAN1ErrorAbortTx = true;
}
else
endif // of ( 1 == MX_FDCAN1 )
if ( 1 == MX_FDCAN2 )
if(FDCAN2== hfdcan->Instance)
{
bCAN2ErrorAbortTx = true;
}
else
endif // of ( 1 == MX_FDCAN2 )
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
rvReadErrorsAndErrorStatuses(hfdcan, poN_ErrorsAndErrorStatuses);
hfdcan->Instance->IR = FDCAN_ERROR_STATUS_FLAGS | FDCAN_ERROR_FLAGS;
poN_ErrorsAndErrorStatuses->u32PreviousFDCAN_IR_Value = poN_ErrorsAndErrorStatuses->u32CurrentFDCAN_IR_Value;
poN_ErrorsAndErrorStatuses->u32CurrentFDCAN_IR_Value = u32IR & ( FDCAN_ERROR_STATUS_FLAGS | FDCAN_ERROR_FLAGS );
}
}
// //- - - - - - - - rvPSCIsAliveResponseTx - - - - - - - // void rvPSCIsAliveResponseTx(FDCAN_HandleTypeDef * phfdcan) { FDCAN_TxHeaderTypeDef oPSCIsAliveResponseTxHeader;
if (1 == MX_FDCAN1)
if(FDCAN1 == phfdcan->Instance)
{
if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
oPSCIsAliveResponseTxHeader = gNoCAN1PSCIsAliveResponseTxHeader;
endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
}
else
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
if(FDCAN2 == phfdcan->Instance)
{
if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
oPSCIsAliveResponseTxHeader = gNoCAN2PSCIsAliveResponseTxHeader;
endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
}
else
endif // of (1 == MX_FDCAN2)
{
// dLEDShowError(dBadCANPort); assert_failed((uint8_t *)FILE, LINE); }
const uint32_t Cu32Size = sizeof(goPSCIsAliveResponse);
if(dMaxBytesTransmittedInOneCANFrame >= Cu32Size)
{
oPSCIsAliveResponseTxHeader.Identifier |= Cu32Size;
oPSCIsAliveResponseTxHeader.DataLength = dDLCBytesValue(Cu32Size);
if (1 == MX_FDCAN1)
if(FDCAN1 == phfdcan->Instance)
{
if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
oPSCIsAliveResponseTxHeader.MessageMarker = u8CAN1CurrentMessageMakerValue; // NOTE: Message Maker value cannot be greater than 255
++u8CAN1CurrentMessageMakerValue;
endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
}
else
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
if(FDCAN2 == phfdcan->Instance)
{
if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
oPSCIsAliveResponseTxHeader.MessageMarker = u8CAN2CurrentMessageMakerValue; // NOTE: Message Maker value cannot be greater than 255
++u8CAN2CurrentMessageMakerValue;
endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
}
else
endif // of (1 == MX_FDCAN2)
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
if(HAL_OK != HAL_FDCAN_AddMessageToTxFifoQ(phfdcan, &oPSCIsAliveResponseTxHeader, (uint8_t *)&oPSCIsAliveResponse))
{
if (1 == MX_FDCAN1)
if(FDCAN1 == phfdcan->Instance)
{
dLEDShowError(dFDCAN1AddMessageToTxFIFO_Fail);
}
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
if(FDCAN2 == phfdcan->Instance)
{
dLEDShowError(dFDCAN2AddMessageToTxFIFO_Fail);
}
endif // of (1 == MX_FDCAN2)
if defined(DRA_TEST_CAN1_TX_FAIL)
HAL_Delay(200);
else // of defined(DRA_TEST_CAN1_TX_FAIL)
assert_failed((uint8_t *)__FILE__, __LINE__);
endif // of defined(DRA_TEST_CAN1_TX_FAIL)
}
if defined(DRA_TEST_CAN1_TX_FAIL)
else
{
static volatile unsigned long uliterations = 0;
uliterations++;
}
endif // of defined(DRA_TEST_CAN1_TX_FAIL)
endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
}
else
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
}
// //- - - - - - - - rvCAN_ReadIncomingFIFO - - - - - - - // void rvCAN_ReadIncomingFIFO(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo, FDCAN_RxHeaderTypeDef * pRxHdr, uint8_t *pData) { uint32_t u32RxFifoFill = HAL_FDCAN_GetRxFifoFillLevel (hfdcan, RxFifo);
if (0 != u32RxFifoFill)
{
HAL_StatusTypeDef nStatus = HAL_FDCAN_GetRxMessage(hfdcan, RxFifo, pRxHdr, pData);
if(HAL_OK != nStatus)
{
if (1 == MX_FDCAN1)
if(FDCAN1 == hfdcan->Instance)
{
dLEDShowError(dFDCAN1GetRxMessageFail);
}
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN2)
if(FDCAN2 == hfdcan->Instance)
{
dLEDShowError(dFDCAN2GetRxMessageFail);
}
endif // of (1 == MX_FDCAN2)
}
}
}
// //- - - - - - - - HAL_FDCAN_RxFifo0Callback - - - - - - - // void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) { uint32_t u32ThisPSCAliveCMI;
if (1 == MX_FDCAN1)
if(FDCAN1 == hfdcan->Instance)
{
if defined(dTestOnlyCANRx)
gu32RxFifo0ITs = RxFifo0ITs;
endif // of defined(dTestOnlyCANRx)
if(FDCAN_IR_RF0L & RxFifo0ITs)
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
if (1 == dCAN1PSCLead)
u32ThisPSCAliveCMI = dIsLeadPSCAliveCMI;
elif (1 == dCAN1PSCTrail) // of (1 == dCAN1PSCLead)
u32ThisPSCAliveCMI = dIsTrailPSCAliveCMI;
endif // of (1 == dCAN1PSCLead)
__schedule_barrier();
rvCAN_ReadIncomingFIFO(hfdcan, FDCAN_RX_FIFO0, (FDCAN_RxHeaderTypeDef *)&oCAN1RxHeader, au8CAN1Payload);
__force_stores();
__schedule_barrier();
if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
// g_u32ThisPSCAliveCMI = u32ThisPSCAliveCMI; // g_ReadCAN_CMI = MulCANMessageIDFromArbitration( oCAN1RxHeader.Identifier ); if(!bCAN1IsPSCAliveMessageReceived && ( u32ThisPSCAliveCMI == MulCANMessageIDFromArbitration( oCAN1RxHeader.Identifier ))) {
if !defined(dTestOnlyCANRx)
bCAN1IsPSCAliveMessageReceived = true;
else // of !defined(dTestOnlyCANRx)
gu32CANRxCounts++;
endif // of !defined(dTestOnlyCANRx)
__force_stores();
}
endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
__schedule_barrier();
}
endif // of (1 == MX_FDCAN1)
if (1 == MX_FDCAN1) && (1 == MX_FDCAN2)
else
endif // of (1 == MX_FDCAN1) && (1 == MX_FDCAN2)
if (1 == MX_FDCAN2)
if(FDCAN2 == hfdcan->Instance)
{
if (1 == dCAN2PSCLead)
u32ThisPSCAliveCMI = dIsLeadPSCAliveCMI;
elif (1 == dCAN2PSCTrail) // of (1 == dCAN2PSCLead)
u32ThisPSCAliveCMI = dIsTrailPSCAliveCMI;
endif // of (1 == dCAN2PSCLead)
__schedule_barrier();
rvCAN_ReadIncomingFIFO(hfdcan, FDCAN_RX_FIFO0, (FDCAN_RxHeaderTypeDef *)&oCAN2RxHeader, au8CAN2Payload);
__force_stores();
__schedule_barrier();
if (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
if(!bCAN2IsPSCAliveMessageReceived && ( u32ThisPSCAliveCMI == MulCANMessageIDFromArbitration( oCAN2RxHeader.Identifier )))
{
bCAN2IsPSCAliveMessageReceived = true;
__force_stores();
}
endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
__schedule_barrier();
}
endif // of (1 == MX_FDCAN2)
}
endif // of ( 1 == MX_FDCAN1 ) || ( 1 == MX_FDCAN2 )
#endif // of (DRA_ENABLE_HW_TEST == DRA_ENABLE_CODE)
Hello @rxa1031,
Thank you for this report, currently there is no plan to implement this fix, as this type of modification may create a compatibility break in the existing applications. So please allow me to close this issue. Thank you for your comprehension.
Best Regards,