/** ****************************************************************************** * @file py32f403_hal_canfd.c * @author MCU Application Team * @brief CANFD HAL module driver. * This file provides firmware functions to manage the following * functionalities of the CAN with Flexible Data-rate (CANFD). * + Initialization and de-initialization functions * + IO operation functions * + Peripheral Control functions * + Peripheral State and Errors functions ****************************************************************************** * @attention * *

© Copyright (c) 2023 Puya Semiconductor Co. * All rights reserved.

* * This software component is licensed by Puya under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** * @attention * *

© Copyright (c) 2016 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "py32f4xx_hal.h" /** @addtogroup PY32F403_HAL_Driver * @{ */ /** @defgroup CANFD CANFD * @brief CANFD driver modules * @{ */ #ifdef HAL_CANFD_MODULE_ENABLED /* Private typedef -----------------------------------------------------------*/ /* Private defines ------------------------------------------------------------*/ /** @defgroup CANFD_Private_Constants CANFD Private Constants * @{ */ #define CANFD_TIMEOUT_VALUE 10U #define CANFD_LLC_EXTENDED_ID_MSK (0x1FFFFFFFU) #define CANFD_LLC_STANDARD_ID_MSK (0x7FF<<18) #define CANFD_LLC_FORMAT_MSK (0x1F1707FF) /** * @} */ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /** @defgroup CANFD_Private_Variables CANFD Private Variables * @{ */ static const uint8_t DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64}; /** * @} */ /* Private function prototypes -----------------------------------------------*/ /** @defgroup CANFD_Private_Functions CANFD Private Functions * @{ */ static void CANFD_CopyMessageToFifo(CANFD_HandleTypeDef *hcanfd, CANFD_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData); /** * @} */ /** @defgroup CANFD_Exported_Functions CANFD Exported Functions * @{ */ /** @defgroup CANFD_Exported_Functions_Group1 Initialization and de-initialization functions * @brief Initialization and Configuration functions * @{ */ /** * @brief CANFD init * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_Init(CANFD_HandleTypeDef *hcanfd) { uint32_t tickstart; /* Check CANFD handle */ if (hcanfd == NULL) { return HAL_ERROR; } /* Check function parameters */ assert_param(IS_CANFD_ALL_INSTANCE(hcanfd->Instance)); assert_param(IS_CANFD_FRAME_FORMAT(hcanfd->Init.FrameFormat)); assert_param(IS_CANFD_MODE(hcanfd->Init.Mode)); assert_param(IS_CANFD_CANFD_PROTOCOL(hcanfd->Init.CANFDProtocol)); assert_param(IS_CANFD_CKDIV(hcanfd->Init.Prescaler)); assert_param(IS_CANFD_NOMINAL_SJW(hcanfd->Init.NominalSyncJumpWidth)); assert_param(IS_CANFD_NOMINAL_TSEG1(hcanfd->Init.NominalTimeSeg1)); assert_param(IS_CANFD_NOMINAL_TSEG2(hcanfd->Init.NominalTimeSeg2)); if (hcanfd->Init.FrameFormat == CANFD_FRAME_FD_BRS) { assert_param(IS_CANFD_DATA_SJW(hcanfd->Init.DataSyncJumpWidth)); assert_param(IS_CANFD_DATA_TSEG1(hcanfd->Init.DataTimeSeg1)); assert_param(IS_CANFD_DATA_TSEG2(hcanfd->Init.DataTimeSeg2)); } assert_param(IS_CANFD_SSPOFF(hcanfd->Init.SecondSamplePointOffset)); if (hcanfd->State == HAL_CANFD_STATE_RESET) { /* Allocate lock resource and initialize it */ hcanfd->Lock = HAL_UNLOCKED; /* Init the low level hardware: CLOCK, NVIC */ HAL_CANFD_MspInit(hcanfd); } /* forces to reset state */ SET_BIT(hcanfd->Instance->MCR, CANFD_MCR_RESET); /* Get tick */ tickstart = HAL_GetTick(); /* Wait until the RESET bit into MCR register is set */ while ((hcanfd->Instance->MCR & CANFD_MCR_RESET) == 0U) { /* Check for the Timeout */ if ((HAL_GetTick() - tickstart) > CANFD_TIMEOUT_VALUE) { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_TIMEOUT; /* Change CAN state */ hcanfd->State = HAL_CANFD_STATE_ERROR; return HAL_ERROR; } } /* Specifies the number of time quanta in Bit */ hcanfd->Instance->ACBTR = (((hcanfd->Init.NominalSyncJumpWidth - 1U) << CANFD_ACBTR_AC_SJW_Pos) + \ ((hcanfd->Init.NominalTimeSeg1 - 2U) << CANFD_ACBTR_AC_SEG_1_Pos) + \ ((hcanfd->Init.NominalTimeSeg2 - 1U) << CANFD_ACBTR_AC_SEG_2_Pos)); /* Specifies functions related to FD frames */ if (hcanfd->Init.FrameFormat == CANFD_FRAME_CLASSIC) { hcanfd->Instance->FDBTR = hcanfd->Instance->ACBTR; } else { if (hcanfd->Init.FrameFormat == CANFD_FRAME_FD_NO_BRS) { hcanfd->Instance->FDBTR = hcanfd->Instance->ACBTR; } else { hcanfd->Instance->FDBTR = (((hcanfd->Init.DataSyncJumpWidth - 1U) << CANFD_FDBTR_FD_SJW_Pos) + \ ((hcanfd->Init.DataTimeSeg1 - 2U) << CANFD_FDBTR_FD_SEG_1_Pos) + \ ((hcanfd->Init.DataTimeSeg2 - 1U) << CANFD_FDBTR_FD_SEG_2_Pos)); } /* Specifies Bosch CAN-FD or 11898-1:2015 CAN-FD */ MODIFY_REG(hcanfd->Instance->MCR, CANFD_MCR_FD_ISO, hcanfd->Init.CANFDProtocol); /* Specifies secondary sample point(SSP) and the length of a time quantum(PRESC)*/ MODIFY_REG(hcanfd->Instance->RLSSP, CANFD_RLSSP_FD_SSPOFF, (hcanfd->Init.SecondSamplePointOffset << CANFD_RLSSP_FD_SSPOFF_Pos)); } MODIFY_REG(hcanfd->Instance->RLSSP, CANFD_RLSSP_PRESC, ((hcanfd->Init.Prescaler - 1U) << CANFD_RLSSP_PRESC_Pos)); /* Initialize the error code */ hcanfd->ErrorCode = HAL_CANFD_ERROR_NONE; /* Initialize the CANFD state */ hcanfd->State = HAL_CANFD_STATE_READY; /* Return function status */ return HAL_OK; } /** * @brief CANFD MSP Init. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_MspInit(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_MspInit could be implemented in the user file */ } #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /** * @brief Register a CANFD CallBack. * To be used instead of the weak predefined callback * @param hcanfd pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for CANFD module * @param CallbackID ID of the callback to be registered * This parameter can be one of the following values: * @arg @ref HAL_CANFD_RX_COMPLETE_CB_ID CANFD Rx complete callback ID * @arg @ref HAL_CANFD_RX_FIFO_ALMOST_FULL_CB_ID CANFD Rx fifo almost full callback ID * @arg @ref HAL_CANFD_RX_FIFO_FULL_CB_ID CANFD Rx fifo full callback ID * @arg @ref HAL_CANFD_PTB_TX_COMPLETE_CB_ID CANFD PTB Tx complete callback ID * @arg @ref HAL_CANFD_STB_TX_COMPLETE_CB_ID CANFD STB Tx complete callback ID * @arg @ref HAL_CANFD_TX_ABORT_CB_ID CANFD Tx abort callback ID * @arg @ref HAL_CANFD_RX_FIFO_OVERFLOW_CB_ID CANFD Rx fifo overflow callback ID * @arg @ref HAL_CANFD_ARBITRATION_LOST_CB_ID CANFD Arbitration lost callback ID * @arg @ref HAL_CANFD_PASSIVE_ERROR_CB_ID CANFD Passive error callback ID * @arg @ref HAL_CANFD_BUS_ERROR_CB_ID CANFD Bus error callback ID * @arg @ref HAL_CANFD_ERROR_CHANGE_CB_ID CANFD Error change callback ID * @arg @ref HAL_CANFD_TT_RX_TIME_TRIG_CB_ID CANFD TT Rx time trig callback ID * @arg @ref HAL_CANFD_TT_TX_SINGLE_TRIG_CB_ID CANFD TT Tx single trig callback ID * @arg @ref HAL_CANFD_TT_TX_START_TRIG_CB_ID CANFD TT Tx start trig callback ID * @arg @ref HAL_CANFD_TT_TX_STOP_TRIG_CB_ID CANFD TT Tx stop trig callback ID * @arg @ref HAL_CANFD_TT_TIMESTAMP_WRAPAROUND_CB_ID CANFD TT timestamp wraparound callback ID * @arg @ref HAL_CANFD_TT_TRIG_ERROR_CB_ID CANFD TT trig error callback ID * @arg @ref HAL_CANFD_MSPINIT_CB_ID MspInit callback ID * @arg @ref HAL_CANFD_MSPDEINIT_CB_ID MspDeInit callback ID * @param pCallback pointer to the Callback function * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_RegisterCallback(CANFD_HandleTypeDef *hcanfd, HAL_CANFD_CallbackIDTypeDef CallbackID, void (* pCallback)(CANFD_HandleTypeDef *_hCANFD)) { HAL_StatusTypeDef status = HAL_OK; if (pCallback == NULL) { /* Update the error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_INVALID_CALLBACK; return HAL_ERROR; } if (hcanfd->State == HAL_CANFD_STATE_READY) { switch (CallbackID) { case HAL_CANFD_RX_COMPLETE_CB_ID : hfdcan->RxCpltCallback = pCallback; break; case HAL_CANFD_RX_FIFO_ALMOST_FULL_CB_ID : hfdcan->RxFifoAlmostFullCallback = pCallback; break; case HAL_CANFD_RX_FIFO_FULL_CB_ID : hfdcan->RxFifoFullCallback = pCallback; break; case HAL_CANFD_PTB_TX_COMPLETE_CB_ID : hfdcan->PtbTxCpltCallback = pCallback; break; case HAL_CANFD_STB_TX_COMPLETE_CB_ID : hfdcan->StbTxCpltCallback = pCallback; break; case HAL_CANFD_TX_ABORT_CB_ID : hfdcan->TxAbortCallback = pCallback; break; case HAL_CANFD_RX_FIFO_OVERFLOW_CB_ID : hfdcan->RxFifoOverflowCallback = pCallback; break; case HAL_CANFD_ARBITRATION_LOST_CB_ID : hfdcan->ArbitrationLostCallback = pCallback; break; case HAL_CANFD_PASSIVE_ERROR_CB_ID : hfdcan->PassiveErrorCallback = pCallback; break; case HAL_CANFD_BUS_ERROR_CB_ID : hfdcan->BusErrorCallback = pCallback; break; case HAL_CANFD_ERROR_CHANGE_CB_ID : hfdcan->ErrorChangeCallback = pCallback; break; case HAL_CANFD_TT_RX_TIME_TRIG_CB_ID : hfdcan->TT_RxTimeTrigCallback = pCallback; break; case HAL_CANFD_TT_TX_SINGLE_TRIG_CB_ID : hfdcan->TT_TxSingleTrigCallback = pCallback; break; case HAL_CANFD_TT_TX_START_TRIG_CB_ID : hfdcan->TT_TxStartTrigCallback = pCallback; break; case HAL_CANFD_TT_TX_STOP_TRIG_CB_ID : hfdcan->TT_TxStopTrigCallback = pCallback; break; case HAL_CANFD_TT_TIMESTAMP_WRAPAROUND_CB_ID : hfdcan->TT_TimestampWraparoundCallback = pCallback; break; case HAL_CANFD_TT_TRIG_ERROR_CB_ID : hfdcan->TT_TrigErrorCallback = pCallback; break; default : /* Update the error code */ hfdcan->ErrorCode |= HAL_CANFD_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; break; } } else if (hcanfd->State == HAL_CANFD_STATE_RESET) { switch (CallbackID) { case HAL_CANFD_MSPINIT_CB_ID : hcanfd->MspInitCallback = pCallback; break; case HAL_CANFD_MSPDEINIT_CB_ID : hcanfd->MspDeInitCallback = pCallback; break; default : /* Update the error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; break; } } else { /* Update the error code */ hfdcan->ErrorCode |= HAL_CANFD_ERROR_INVALID_CALLBACK; /* Return error status */ status = HAL_ERROR; } return status; } #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ /** * @} */ /** @defgroup CANFD_Exported_Functions_Group2 IO operation functions * @brief Configuration functions. * @{ */ /** * @brief Config CANFD filter * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param sFilter pointer to an CANFD_FilterTypeDef structure. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ConfigFilter(CANFD_HandleTypeDef *hcanfd, CANFD_FilterTypeDef *sFilter) { HAL_CANFD_StateTypeDef state = hcanfd->State; /* Check function parameters */ assert_param(IS_CANFD_ID_TYPE(sFilter->IdType)); assert_param(IS_CANFD_FILTER_CHANNEL(sFilter->FilterChannel)); assert_param(IS_CANFD_RANK(sFilter->Rank)); assert_param(IS_CANFD_FILTER_ID(sFilter->FilterID)); assert_param(IS_CANFD_FILTER_FORMAT(sFilter->FilterFormat)); assert_param(IS_CANFD_MASK_ID(sFilter->MaskID)); assert_param(IS_CANFD_MASK_FORMAT(sFilter->MaskFormat)); if (state == HAL_CANFD_STATE_READY) { if (sFilter->Rank == CANFD_FILTER_RANK_NONE) { /* Disable Filter channel */ CLEAR_BIT(hcanfd->Instance->ACFCR, (1U << (CANFD_ACFCR_AE_0_Pos + sFilter->FilterChannel))); } else { /* Specify acceptance filter address */ MODIFY_REG(hcanfd->Instance->ACFCR, CANFD_ACFCR_ACFADR, sFilter->FilterChannel); /* Specify acceptance code Identifier and mask Identifier */ if (sFilter->IdType == CANFD_STANDARD_ID) { hcanfd->Instance->ACFC.ID = sFilter->FilterID << 18; hcanfd->Instance->ACFM.ID = (~CANFD_LLC_STANDARD_ID_MSK) | (sFilter->MaskID << 18); } else { hcanfd->Instance->ACFC.ID = sFilter->FilterID; hcanfd->Instance->ACFM.ID = (~CANFD_LLC_EXTENDED_ID_MSK) | (sFilter->MaskID); } /* Specify acceptance code Format */ hcanfd->Instance->ACFC.FORMAT = sFilter->FilterFormat; /* Specify acceptance mask Format */ hcanfd->Instance->ACFM.FORMAT = (~CANFD_LLC_FORMAT_MSK) | (sFilter->MaskFormat); /* Specify acceptance mask Type */ hcanfd->Instance->ACFM.TYPE = 0xFFFFFFFF; /* Specify acceptance mask Acceptance Field */ hcanfd->Instance->ACFM.Reserved = 0xFFFFFFFF; /* Enable Filter channel*/ SET_BIT(hcanfd->Instance->ACFCR, (1U << (CANFD_ACFCR_AE_0_Pos + sFilter->FilterChannel))); } /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_INITIALIZED; return HAL_ERROR; } } /** * @brief Add a message to the Tx FIFO * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param pTxHeader pointer to an CANFD_TxHeaderTypeDef structure. * @param pData pointer to a buffer containing the payload of the Tx frame. * @param TxFifoType Tx FIFO type. * This parameter can be a value of @arg CANFD_fifo_type. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_AddMessageToTxFifo(CANFD_HandleTypeDef *hcanfd, CANFD_TxHeaderTypeDef *pTxHeader, uint8_t *pData, uint32_t TxFifoType) { /* Check function parameters */ assert_param(IS_CANFD_ID_TYPE(pTxHeader->IdType)); if (pTxHeader->IdType == CANFD_STANDARD_ID) { assert_param(IS_CANFD_MAX_VALUE(pTxHeader->Identifier, 0x7FFU)); } else /* pTxHeader->IdType == CANFD_EXTENDED_ID */ { assert_param(IS_CANFD_MAX_VALUE(pTxHeader->Identifier, 0x1FFFFFFFU)); } assert_param(IS_CANFD_TX_FRAME_TYPE(pTxHeader->TxFrameType)); assert_param(IS_CANFD_FRAME_FORMAT(pTxHeader->FrameFormat)); assert_param(IS_CANFD_Handle(pTxHeader->Handle)); assert_param(IS_CANFD_DLC(pTxHeader->DataLength)); assert_param(IS_CANFD_TX_FIFO_TYPE(TxFifoType)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { if (TxFifoType == CANFD_TX_FIFO_PTB) { /* select PTB FIFO */ CLEAR_BIT(hcanfd->Instance->MCR, CANFD_MCR_TBSEL); /* check that the PTB FIFO is not full */ if (READ_BIT(hcanfd->Instance->MCR, CANFD_MCR_TPE) == 0) { /* Write data to the FIFO */ CANFD_CopyMessageToFifo(hcanfd, pTxHeader, pData); } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_FIFO_FULL; /* The PTB is transmitting data, Cannot write data to PTB FIFO */ return HAL_ERROR; } } else { /* select STB FIFO */ SET_BIT(hcanfd->Instance->MCR, CANFD_MCR_TBSEL); /* check that the STB FIFO is not full */ if (__HAL_CANFD_GET_STB_FIFO_FREE_LEVEL(hcanfd) != CANFD_STB_FIFO_FULL) { /* Write data to the FIFO */ CANFD_CopyMessageToFifo(hcanfd, pTxHeader, pData); /* this slot has been filled, CAN-CTRL connects the TBUF registers to the next slot.*/ SET_BIT(CANFD->MCR, CANFD_MCR_TSNEXT); } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_FIFO_FULL; /* The STB FIFO is full and cannot be written */ return HAL_ERROR; } } return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Activation the message is sent from Tx FIFO to the bus * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param activeTxMode Select the sending mode * This parameter can be a value of @arg CANFD_transmit_mode. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ActivateTxRequest(CANFD_HandleTypeDef *hcanfd, uint32_t activeTxMode) { /* Check function parameters */ assert_param(IS_CANFD_TRANSMIT_MODE(activeTxMode)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { if (activeTxMode == CANFD_TXFIFO_PTB_SEND) { /* PTB FIFO data start sending */ SET_BIT(hcanfd->Instance->MCR,CANFD_MCR_TPE); } if (activeTxMode == CANFD_TXFIFO_STB_SEND_ONE) { /* Transmit STB FIFO one frame */ SET_BIT(hcanfd->Instance->MCR,CANFD_MCR_TSONE); hcanfd->LastSTBTxType = CANFD_TXFIFO_STB_SEND_ONE; } else if (activeTxMode == CANFD_TXFIFO_STB_SEND_ALL) { /* Transmit STB FIFO all frame */ SET_BIT(hcanfd->Instance->MCR,CANFD_MCR_TSALL); hcanfd->LastSTBTxType = CANFD_TXFIFO_STB_SEND_ALL; } return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Get Tx FIFO message * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param pRxHeader pointer to an CANFD_RxHeaderTypeDef structure. * @param pRxData pointer to a buffer containing the payload of the Rx frame. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_GetRxMessage(CANFD_HandleTypeDef *hcanfd, CANFD_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData) { uint8_t *pData; uint32_t ByteCounter; uint32_t Format; if (hcanfd->State == HAL_CANFD_STATE_BUSY) { if (__HAL_CANFD_GET_RX_FIFO_FILL_LEVEL(hcanfd) == CANFD_RX_FIFO_EMPTY) { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_FIFO_FULL; return HAL_ERROR; } Format = hcanfd->Instance->RBUF.FORMAT; pRxHeader->DataLength = Format & CANFD_LLC_FORMAT_DLC; pRxHeader->IdType = Format & CANFD_LLC_FORMAT_IDE; pRxHeader->RxFrameType = Format & CANFD_LLC_FORMAT_RMF; pRxHeader->FrameFormat = Format & (CANFD_LLC_FORMAT_BRS | CANFD_LLC_FORMAT_FDF); pRxHeader->ProtocolErrorType = (Format & CANFD_LLC_FORMAT_KOER)>>CANFD_LLC_FORMAT_KOER_Pos; pRxHeader->ErrorStateIndicator = Format & CANFD_LLC_FORMAT_ESI; pRxHeader->LoopBackIndicator = Format & CANFD_LLC_FORMAT_LBF; if (pRxHeader->IdType == CANFD_EXTENDED_ID) { pRxHeader->Identifier = hcanfd->Instance->RBUF.ID & CANFD_LLC_EXTENDED_ID_MSK; } else { pRxHeader->Identifier = (hcanfd->Instance->RBUF.ID & CANFD_LLC_STANDARD_ID_MSK) >> 18; } /* Retrieve Rx payload */ pData = (uint8_t *)hcanfd->Instance->RBUF.DATA; for (ByteCounter = 0; ByteCounter < DLCtoBytes[pRxHeader->DataLength]; ByteCounter++) { pRxData[ByteCounter] = pData[ByteCounter]; } /* The host controller has read the actual RB slot and releases it. Afterwards CAN-CTRL points to the next RB slot.*/ SET_BIT(CANFD->MCR, CANFD_MCR_RREL); return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Abort the message is sent from Tx FIFO to the bus * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param TransmitType Select a send mode to abort * This parameter can be a value of @arg CANFD_transmit_mode. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_AbortTxRequest(CANFD_HandleTypeDef *hcanfd, uint32_t TransmitType) { /* Check function parameters */ assert_param(IS_CANFD_TRANSMIT_MODE(TransmitType)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { if (TransmitType == CANFD_TXFIFO_PTB_SEND) { /* Abort PTB FIFO data transmission */ SET_BIT(hcanfd->Instance->MCR,CANFD_MCR_TPA); } if ((TransmitType == CANFD_TXFIFO_STB_SEND_ONE) || (TransmitType == CANFD_TXFIFO_STB_SEND_ALL)) { /* Abort STB FIFO data transmission */ SET_BIT(hcanfd->Instance->MCR,CANFD_MCR_TSA); } hcanfd->LastAbortTxType = TransmitType; return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Config CANFD Re-arbitration limit. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param reaLimit indicates Re-arbitration limit value. * This parameter can be a value of @arg CANFD_rearbitration_Limit. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ConfigRearbitrationLimit(CANFD_HandleTypeDef *hcanfd, uint32_t reaLimit) { /* Check function parameters */ assert_param(IS_CANFD_REARBITRATION_LIMIT(reaLimit)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->RLSSP, CANFD_RLSSP_REALIM, reaLimit); return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Config CANFD Re-transmission limit. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param retLimit indicates Re-transmission limit value. * This parameter can be a value of @arg CANFD_retransmission_Limit. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ConfigRetransmissionLimit(CANFD_HandleTypeDef *hcanfd, uint32_t retLimit) { /* Check function parameters */ assert_param(IS_CANFD_RETRANSMISSION_LIMIT(retLimit)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->RLSSP, CANFD_RLSSP_RETLIM, retLimit); /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Config the Priority mode of STB Buffer transmit. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param StbPriority the Priority mode of STB Buffer transmit. * This parameter can be a value of @arg CANFD_STB_Priority_Mode. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ConfigTxFifoPriority(CANFD_HandleTypeDef *hcanfd, uint32_t StbPriority) { /* Check function parameters */ assert_param(IS_CANFD_STB_PRIORITY(StbPriority)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->MCR, CANFD_MCR_TSMODE, StbPriority); /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Configure the STB FIFO operation mode. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param OverflowMode CAN Receive Buffer Overflow Mode. * This parameter can be a value of @arg CANFD_RX_FIFO_overflow_mode. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ConfigRxFifoOverwrite(CANFD_HandleTypeDef *hcanfd, uint32_t OverflowMode) { /* Check function parameters */ assert_param(IS_CANFD_RX_FIFO_MODE(OverflowMode)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->MCR, CANFD_MCR_ROM, OverflowMode); /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Configure receive buffer almost full warning limit. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param Threshold receive buffer almost full warning limit. * This parameter can be a value of @arg CANFD_RX_FIFO_threshold. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ConfigRxFifoThreshold(CANFD_HandleTypeDef *hcanfd, uint32_t Threshold) { /* Check function parameters */ assert_param(IS_CANFD_RX_FIFO_THRESHOLD(Threshold)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->WECR, CANFD_WECR_AFWL, Threshold); /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Enable CANFD receive error data frame. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_EnableReceiveErrorDataFrame(CANFD_HandleTypeDef *hcanfd) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { /* Enable transmitter delay compensation */ SET_BIT(hcanfd->Instance->MCR, CANFD_MCR_RBALL); /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Disable CANFD receive error data frame. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_DisableReceiveErrorDataFrame(CANFD_HandleTypeDef *hcanfd) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { /* Enable transmitter delay compensation */ CLEAR_BIT(hcanfd->Instance->MCR, CANFD_MCR_RBALL); /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Enable CANFD receive error data frame. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param pTTConfig pointer to an CANFD_TimeTriggerTypeDef structure. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_TT_Config(CANFD_HandleTypeDef *hcanfd, CANFD_TimeTriggerTypeDef *pTTConfig) { /* Check function parameters */ assert_param(IS_CANFD_TT_FIFO_MODE(pTTConfig->FifoMode)); assert_param(IS_CANFD_TT_PRESCALER(pTTConfig->Prescaler)); if (pTTConfig->RefMessageIdType == CANFD_STANDARD_ID) { assert_param(IS_CANFD_MAX_VALUE(pTTConfig->RefMessageId, 0x7FFU)); } else /* pTxHeader->IdType == CANFD_EXTENDED_ID */ { assert_param(IS_CANFD_MAX_VALUE(pTTConfig->RefMessageId, 0x1FFFFFFFU)); } assert_param(IS_CANFD_TX_ENABLE_WINDOW(pTTConfig->TxEnableWindow)); assert_param(IS_CANFD_WATCH_TRIG_TIME(pTTConfig->WatchTrigTime)); if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->MCR, CANFD_MCR_TTTBM, pTTConfig->FifoMode); if (pTTConfig->RefMessageIdType == CANFD_STANDARD_ID) { WRITE_REG(hcanfd->Instance->REFMSG, (pTTConfig->RefMessageId)); } else { WRITE_REG(hcanfd->Instance->REFMSG, (0x80000000 | pTTConfig->RefMessageId)); } MODIFY_REG(hcanfd->Instance->TTTR, CANFD_TTTR_TT_WTRIG,(pTTConfig->WatchTrigTime<Instance->TTCR, (CANFD_TTCR_T_PRESC | CANFD_TTCR_TEW), (pTTConfig->Prescaler | (pTTConfig->TxEnableWindow << CANFD_TTCR_TEW_Pos))); SET_BIT(hcanfd->Instance->TTCR, CANFD_TTCR_TTEN); return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Add a message to the time trig FIFO * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param txHeader pointer to an CANFD_TxHeaderTypeDef structure. * @param pData pointer to a buffer containing the payload of the Tx frame. * @param slotIndex the fifo index * This parameter can be a value of @arg CANFD_TT_FIFO_INDEX. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_TT_AddMessageToFifo(CANFD_HandleTypeDef *hcanfd, CANFD_TxHeaderTypeDef *txHeader, uint8_t *pData, uint32_t slotIndex) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->TTCR, CANFD_TTCR_TBPTR, (slotIndex<Instance->MCR, CANFD_MCR_TSFF) == 0) { /* Write data to the FIFO */ CANFD_CopyMessageToFifo(hcanfd, txHeader, pData); /* Notifies CANFD that the slot is filled */ SET_BIT(CANFD->TTCR, CANFD_TTCR_TBF); } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_FIFO_FULL; return HAL_ERROR; } return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Activate TTCAN Trigger Request. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param triggerType TTCAN trigger type. * This parameter can be a value of @arg CANFD_TT_trigger_type. * @param trigTime TTCAN trigger time. * @param slotIndex the fifo index * This parameter can be a value of @arg CANFD_TT_FIFO_INDEX. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_TT_ActivateTrigRequest(CANFD_HandleTypeDef *hcanfd, uint32_t triggerType, uint32_t trigTime, uint32_t slotIndex) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(CANFD->TTCR, (CANFD_TTCR_TTPTR | CANFD_TTCR_TTYPE), ((slotIndex<TTTR, CANFD_TTTR_TT_TRIG, (trigTime<LastTimeTrigType = triggerType; return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief TTCAN mode,set TB slot to empty. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param slotIndex TB SLOT index. * This parameter can be a value of @arg CANFD_TT_FIFO_INDEX. * @param slotState Set TB SLOT state * This parameter can be a value of @arg CANFD_TT_FIFO_State_Set. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_TT_ConfigTxBufferState(CANFD_HandleTypeDef *hcanfd, uint32_t slotIndex, uint32_t slotState) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { MODIFY_REG(hcanfd->Instance->TTCR, CANFD_TTCR_TBPTR, (slotIndex<TTCR, (CANFD_TTCR_TBE | CANFD_TTCR_TBF), slotState); return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Start the CANFD module. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_Start(CANFD_HandleTypeDef *hcanfd) { uint32_t tickstart; if (hcanfd->State == HAL_CANFD_STATE_READY) { /* Change CANFD peripheral state */ hcanfd->State = HAL_CANFD_STATE_BUSY; /* Request leave initialisation */ CLEAR_BIT(hcanfd->Instance->MCR, CANFD_MCR_RESET); /* Get tick */ tickstart = HAL_GetTick(); /* Wait until the RESET bit into MCR register is set */ while ((hcanfd->Instance->MCR & CANFD_MCR_RESET) != 0) { /* Check for the Timeout */ if ((HAL_GetTick() - tickstart) > CANFD_TIMEOUT_VALUE) { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_TIMEOUT; /* Change CAN state */ hcanfd->State = HAL_CANFD_STATE_ERROR; return HAL_ERROR; } } /* Specifies the CANFD working mode */ if (hcanfd->Init.Mode == CANFD_MODE_RESTRICTED_OPERATION) { SET_BIT(hcanfd->Instance->TSNCR, CANFD_TSNCR_ROP); } else { MODIFY_REG(hcanfd->Instance->MCR, (CANFD_MCR_LBME | CANFD_MCR_LBMI | CANFD_MCR_SACK | CANFD_MCR_LOM), \ hcanfd->Init.Mode); } /* Reset the CANFD ErrorCode */ hcanfd->ErrorCode = HAL_CANFD_ERROR_NONE; /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_READY; return HAL_ERROR; } } /** * @brief Enable interrupts. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param activeITs indicates which interrupts will be enabled. * This parameter can be any combination of @arg CANFD_Interrupts. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ActivateNotification(CANFD_HandleTypeDef *hcanfd, uint32_t activeITs) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { __HAL_CANFD_ENABLE_IT(hcanfd, activeITs); return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Disable interrupts. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param inactiveITs indicates which interrupts will be disabled. * This parameter can be any combination of @arg CANFD_Interrupts. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_DeactivateNotification(CANFD_HandleTypeDef *hcanfd, uint32_t inactiveITs) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { __HAL_CANFD_DISABLE_IT(hcanfd, inactiveITs); return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief CANFD enter standby mode. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_EnterStandbyMode(CANFD_HandleTypeDef *hcanfd) { uint32_t tickstart; if (hcanfd->State == HAL_CANFD_STATE_BUSY) { SET_BIT(hcanfd->Instance->MCR, CANFD_MCR_STBY); /* Get tick */ tickstart = HAL_GetTick(); while (READ_BIT(hcanfd->Instance->MCR, CANFD_MCR_STBY) == 0) { /* Check for the Timeout */ if ((HAL_GetTick() - tickstart) > CANFD_TIMEOUT_VALUE) { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_TIMEOUT; return HAL_ERROR; } SET_BIT(hcanfd->Instance->MCR, CANFD_MCR_STBY); } return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief CANFD exit standby mode. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_ExitStandbyMode(CANFD_HandleTypeDef *hcanfd) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { CLEAR_BIT(hcanfd->Instance->MCR, CANFD_MCR_STBY); return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief Get protocol status. * @param hcanfd pointer to an FDCAN_HandleTypeDef structure that contains * the configuration information for the specified FDCAN. * @param ProtocolStatus pointer to an FDCAN_ProtocolStatusTypeDef structure. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_GetProtocolStatus(CANFD_HandleTypeDef *hcanfd, CANFD_ProtocolStatusTypeDef *ProtocolStatus) { uint32_t StatusReg; /* Read the protocol status register */ StatusReg = READ_REG(hcanfd->Instance->WECR); /* Fill the protocol status structure */ ProtocolStatus->LastArbLostPos = ((StatusReg & CANFD_WECR_ALC) >> CANFD_WECR_ALC_Pos); ProtocolStatus->LastErrorCode = ((StatusReg & CANFD_WECR_KOER) >> CANFD_WECR_KOER_Pos); ProtocolStatus->RxErrorCnt = ((StatusReg & CANFD_WECR_RECNT) >> CANFD_WECR_RECNT_Pos); ProtocolStatus->TxErrorCnt = ((StatusReg & CANFD_WECR_TECNT) >> CANFD_WECR_TECNT_Pos); StatusReg = READ_REG(hcanfd->Instance->IFR); if ((StatusReg & CANFD_IFR_EPASS) != 0) { ProtocolStatus->ErrorPassive = 1; } else { ProtocolStatus->ErrorPassive = 0; } if ((StatusReg & CANFD_IFR_EWARN) != 0) { ProtocolStatus->Warning = 1; } else { ProtocolStatus->Warning = 0; } ProtocolStatus->BusOff = READ_BIT(hcanfd->Instance->MCR, CANFD_MCR_BUSOFF); /* Return function status */ return HAL_OK; } /** * @brief Get transmit status. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param TxStatus pointer to an CANFD_TxStatusTypeDef structure. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_GetTransmitStatus(CANFD_HandleTypeDef *hcanfd, CANFD_TxStatusTypeDef *TxStatus) { uint32_t StatusReg; /* Read the protocol status register */ StatusReg = READ_REG(hcanfd->Instance->TSR); /* Fill the protocol status structure */ TxStatus->LastTxHandle = ((StatusReg & CANFD_TSR_HANDLE_H) >> CANFD_TSR_HANDLE_H_Pos); TxStatus->LastTxStatus = ((StatusReg & CANFD_TSR_TSTAT_H) >> CANFD_TSR_TSTAT_H_Pos); TxStatus->TxHandle = ((StatusReg & CANFD_TSR_HANDLE_L) >> CANFD_TSR_HANDLE_L_Pos); TxStatus->TxStatus = ((StatusReg & CANFD_TSR_TSTAT_L) >> CANFD_TSR_TSTAT_L_Pos); /* Return function status */ return HAL_OK; } /** * @brief Stop the CANFD module. * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @retval HAL status */ HAL_StatusTypeDef HAL_CANFD_Stop(CANFD_HandleTypeDef *hcanfd) { if (hcanfd->State == HAL_CANFD_STATE_BUSY) { /* forces to reset state */ SET_BIT(hcanfd->Instance->MCR, CANFD_MCR_RESET); /* Reset the CANFD ErrorCode */ hcanfd->ErrorCode = HAL_CANFD_ERROR_NONE; /* Change CANFD peripheral state */ hcanfd->State = HAL_CANFD_STATE_READY; /* Return function status */ return HAL_OK; } else { /* Update error code */ hcanfd->ErrorCode |= HAL_CANFD_ERROR_NOT_STARTED; return HAL_ERROR; } } /** * @brief This function handles CANFD interrupt request. * @param hcanfd Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ void HAL_CANFD_IRQHandler(CANFD_HandleTypeDef *hcanfd) { /* Receive Interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_RX_COMPLETE) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_RX_COMPLETE) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_RX_COMPLETE); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->RxCpltCallback(hcanfd); #else /* Recieve Complete Callback */ HAL_CANFD_RxCpltCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* RB Almost Full Interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_RX_FIFO_ALMOST_FULL) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_RX_FIFO_ALMOST_FULL) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_RX_FIFO_ALMOST_FULL); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->RxFifoAlmostFullCallback(hcanfd); #else /* Recieve fifo almost full Callback */ HAL_CANFD_RxFifoAlmostFullCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* RB Full Interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_RX_FIFO_FULL) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_RX_FIFO_FULL) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_RX_FIFO_FULL); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->RxFifoFullCallback(hcanfd); #else /* Recieve fifo full Callback */ HAL_CANFD_RxFifoFullCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Transmission Primary Interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_TX_PTB_COMPLETE) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_TX_PTB_COMPLETE) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_TX_PTB_COMPLETE); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->PtbTxCpltCallback(hcanfd); #else /* PTB Transmit complete Callback */ HAL_CANFD_PtbTxCpltCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Transmission Secondary Interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_TX_STB_COMPLETE) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_TX_STB_COMPLETE) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_TX_STB_COMPLETE); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->StbTxCpltCallback(hcanfd); #else /* STB Transmit complete Callback */ HAL_CANFD_StbTxCpltCallback(hcanfd, hcanfd->LastSTBTxType); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Abort Interrupt */ if (__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_TX_ABORT_COMPLETE) != 0U) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_TX_ABORT_COMPLETE); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->TxAbortCallback(hcanfd); #else /* Abort Interrupt Callback */ HAL_CANFD_TxAbortCallback(hcanfd, hcanfd->LastAbortTxType); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Time Trigger Interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_TRIGGER_COMPLETE) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_TRIGGER_COMPLETE) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_TRIGGER_COMPLETE); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ if (hcanfd->LastTimeTrigType == CANFD_TT_RX_TIME_TRIG) { hcanfd->TT_RxTimeTrigCallback(hcanfd); } else if (hcanfd->LastTimeTrigType == CANFD_TT_TX_SINGLE_TRIG) { hcanfd->TT_TxSingleTrigCallback(hcanfd); } else if (hcanfd->LastTimeTrigType == CANFD_TT_TX_START_TRIG) { hcanfd->TT_TxStartTrigCallback(hcanfd); } else if (hcanfd->LastTimeTrigType == CANFD_TT_TX_STOP_TRIG) { hcanfd->TT_TxStopTrigCallback(hcanfd); } #else /* TTCAN Callback */ if (hcanfd->LastTimeTrigType == CANFD_TT_RX_TIME_TRIG) { HAL_CANFD_TT_RxTimeTrigCallback(hcanfd); } else if (hcanfd->LastTimeTrigType == CANFD_TT_TX_SINGLE_TRIG) { HAL_CANFD_TT_TxSingleTrigCallback(hcanfd); } else if (hcanfd->LastTimeTrigType == CANFD_TT_TX_START_TRIG) { HAL_CANFD_TT_TxStartTrigCallback(hcanfd); } else if (hcanfd->LastTimeTrigType == CANFD_TT_TX_STOP_TRIG) { HAL_CANFD_TT_TxStopTrigCallback(hcanfd); } #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Watch Trigger Interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_TIMESTAMP_WRAPAROUND) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_TIMESTAMP_WRAPAROUND) != 0U)) { /* Clear the Timestamp Wraparound flag */ __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_TIMESTAMP_WRAPAROUND); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->TimestampWraparoundCallback(hcanfd); #else /* Timestamp Wraparound Callback */ HAL_CANFD_TT_TimestampWraparoundCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Error interrupt */ if (((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_ALL_ERROR) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_ALL_ERROR) != 0U)) ||\ (__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_TRIGGER_ERROR) != 0U)) { /* interrupt of Overflow of CANFD Rx FIFO */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_RX_FIFO_OVERFLOW) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_RX_FIFO_OVERFLOW) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_RX_FIFO_OVERFLOW); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->RxFifoOverflowCallback(hcanfd); #else /* Receive fifo overflow Callback */ HAL_CANFD_RxFifoOverflowCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Arbitration lost interrupt*/ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_ARB_LOST) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_ARB_LOST) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_ARB_LOST); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->ArbitrationLostCallback(hcanfd); #else /* Arbitration lost Callback */ HAL_CANFD_ArbitrationLostCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Error_Passive interrupt*/ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_ERROR_PASSIVE) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_ERROR_PASSIVE) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_ERROR_PASSIVE); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->PassiveErrorCallback(hcanfd); #else /* Passive error Callback */ HAL_CANFD_PassiveErrorCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* bus error interrupt */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_BUS_ERROR) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_BUS_ERROR) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_BUS_ERROR); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->BusErrorCallback(hcanfd); #else /* Bus error Callback */ HAL_CANFD_BusErrorCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* interrupt of Bus_Off status changed or Error_Passive status changed */ if ((__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_ERROR_TOGGLE) != 0U) && \ (__HAL_CANFD_GET_IT_SOURCE(hcanfd, CANFD_IT_ERROR_TOGGLE) != 0U)) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_ERROR_TOGGLE); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->ErrorChangeCallback(hcanfd); #else /* Error change Callback */ HAL_CANFD_ErrorChangeCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } /* Trigger error Interrupt */ if (__HAL_CANFD_GET_FLAG(hcanfd, CANFD_FLAG_TRIGGER_ERROR) != 0U) { __HAL_CANFD_CLEAR_FLAG(hcanfd, CANFD_FLAG_TRIGGER_ERROR); #if USE_HAL_CANFD_REGISTER_CALLBACKS == 1 /* Call registered callback*/ hcanfd->TT_TrigErrorCallback(hcanfd); #else /* TTCAN trig error Callback */ HAL_CANFD_TT_TrigErrorCallback(hcanfd); #endif /* USE_HAL_CANFD_REGISTER_CALLBACKS */ } } } /** * @brief Recieve Complete Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_RxCpltCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_RxCpltCallback could be implemented in the user file */ } /** * @brief Recieve fifo almost full Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_RxFifoAlmostFullCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_RxFifoAlmostFullCallback could be implemented in the user file */ } /** * @brief Recieve fifo full Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_RxFifoFullCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_RxFifoFullCallback could be implemented in the user file */ } /** * @brief PTB Transmit complete Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_PtbTxCpltCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_PtbTxCpltCallback could be implemented in the user file */ } /** * @brief STB Transmit complete Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @param LastSTBTxType CAN last STB transmit type. * @retval None */ __weak void HAL_CANFD_StbTxCpltCallback(CANFD_HandleTypeDef *hcan, uint32_t LastSTBTxType) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_StbTxCpltCallback could be implemented in the user file */ } /** * @brief Receive fifo overflow Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_RxFifoOverflowCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_RxFifoOverflowCallback could be implemented in the user file */ } /** * @brief Arbitration lost Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_ArbitrationLostCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_ArbitrationLostCallback could be implemented in the user file */ } /** * @brief Abort Interrupt Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @param LastAbortTxType CAN last abort transmit type. * @retval None */ __weak void HAL_CANFD_TxAbortCallback(CANFD_HandleTypeDef *hcan, uint32_t LastAbortTxType) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_TxAbortCallback could be implemented in the user file */ } /** * @brief Passive error Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_PassiveErrorCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_PassiveErrorCallback could be implemented in the user file */ } /** * @brief Bus error Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_BusErrorCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_BusErrorCallback could be implemented in the user file */ } /** * @brief Error change Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_ErrorChangeCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_ErrorChangeCallback could be implemented in the user file */ } /** * @brief TTCAN rx timer trigger callbacks. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_TT_RxTimeTrigCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_TT_RxTimeTrigCallback could be implemented in the user file */ } /** * @brief TTCAN tx singger trigger callbacks. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_TT_TxSingleTrigCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_TT_TxSingleTrigCallback could be implemented in the user file */ } /** * @brief TTCAN tx start trigger callbacks. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_TT_TxStartTrigCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_TT_TxStartTrigCallback could be implemented in the user file */ } /** * @brief TTCAN tx stop trigger callbacks. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_TT_TxStopTrigCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_TT_TxStopTrigCallback could be implemented in the user file */ } /** * @brief Timestamp Wraparound Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_TT_TimestampWraparoundCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_TT_TimestampWraparoundCallback could be implemented in the user file */ } /** * @brief TTCAN trig error Callback. * @param hcan Pointer to a CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD module. * @retval None */ __weak void HAL_CANFD_TT_TrigErrorCallback(CANFD_HandleTypeDef *hcan) { /* Prevent unused argument(s) compilation warning */ UNUSED(hcan); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_CANFD_TT_TrigErrorCallback could be implemented in the user file */ } /** * @} */ /** * @} */ /** @addtogroup CANFD_Private_Functions * @{ */ /** * @brief Copy message to transmit FIFO * @param hcanfd pointer to an CANFD_HandleTypeDef structure that contains * the configuration information for the specified CANFD. * @param pTxHeader pointer to an CANFD_TxHeaderTypeDef structure. * @param pTxData pointer to a buffer containing the payload of the Tx frame. * @retval HAL status */ static void CANFD_CopyMessageToFifo(CANFD_HandleTypeDef *hcanfd, CANFD_TxHeaderTypeDef *pTxHeader, uint8_t *pTxData) { uint32_t index; uint32_t ByteCounter; /* Specify TBUF Identifier */ if (pTxHeader->IdType == CANFD_STANDARD_ID) { hcanfd->Instance->TBUF.ID = pTxHeader->Identifier << 18; } else { hcanfd->Instance->TBUF.ID = pTxHeader->Identifier; } /* Specify TBUF FORMAT */ hcanfd->Instance->TBUF.FORMAT = pTxHeader->DataLength | pTxHeader->IdType | pTxHeader->FrameFormat | pTxHeader->TxFrameType; /* Specify TBUF HANDLE */ hcanfd->Instance->TBUF.TYPE = pTxHeader->Handle << 24; /* Write Tx payload to the message RAM */ index = 0; for (ByteCounter = 0; ByteCounter < DLCtoBytes[pTxHeader->DataLength]; ByteCounter += 4U) { hcanfd->Instance->TBUF.DATA[index++] = (((uint32_t)pTxData[ByteCounter + 3U] << 24U) | ((uint32_t)pTxData[ByteCounter + 2U] << 16U) | ((uint32_t)pTxData[ByteCounter + 1U] << 8U) | (uint32_t)pTxData[ByteCounter]); } } /** * @} */ #endif /* HAL_CANFD_MODULE_ENABLED */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT Puya *****END OF FILE****/