You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1889 lines
59 KiB
C

/**
******************************************************************************
* @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
*
* <h2><center>&copy; Copyright (c) 2023 Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* 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
*
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2>
*
* 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<<CANFD_TTTR_TT_WTRIG_Pos));
MODIFY_REG(hcanfd->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<<CANFD_TTCR_TBPTR_Pos));
if (READ_BIT(hcanfd->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<<CANFD_TTCR_TTPTR_Pos) | triggerType));
MODIFY_REG(CANFD->TTTR, CANFD_TTTR_TT_TRIG, (trigTime<<CANFD_TTTR_TT_TRIG_Pos));
hcanfd->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<<CANFD_TTCR_TBPTR_Pos));
MODIFY_REG(CANFD->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****/