|
@@ -3,79 +3,134 @@
|
|
|
* @file stm32f1xx_hal_can.c
|
|
|
* @author MCD Application Team
|
|
|
* @brief CAN HAL module driver.
|
|
|
- * This file provides firmware functions to manage the following
|
|
|
- * functionalities of the Controller Area Network (CAN) peripheral:
|
|
|
- * + Initialization and de-initialization functions
|
|
|
- * + IO operation functions
|
|
|
- * + Peripheral Control functions
|
|
|
+ * This file provides firmware functions to manage the following
|
|
|
+ * functionalities of the Controller Area Network (CAN) peripheral:
|
|
|
+ * + Initialization and de-initialization functions
|
|
|
+ * + Configuration functions
|
|
|
+ * + Control functions
|
|
|
+ * + Interrupts management
|
|
|
+ * + Callbacks functions
|
|
|
* + Peripheral State and Error functions
|
|
|
*
|
|
|
@verbatim
|
|
|
==============================================================================
|
|
|
##### How to use this driver #####
|
|
|
==============================================================================
|
|
|
- [..]
|
|
|
- (#) Enable the CAN controller interface clock using
|
|
|
- __HAL_RCC_CAN1_CLK_ENABLE() for CAN1 and __HAL_RCC_CAN2_CLK_ENABLE() for CAN2
|
|
|
- -@- In case you are using CAN2 only, you have to enable the CAN1 clock.
|
|
|
-
|
|
|
- (#) CAN pins configuration
|
|
|
- (++) Enable the clock for the CAN GPIOs using the following function:
|
|
|
- __HAL_RCC_GPIOx_CLK_ENABLE();
|
|
|
- (++) Connect and configure the involved CAN pins using the
|
|
|
- following function HAL_GPIO_Init();
|
|
|
-
|
|
|
- (#) Initialize and configure the CAN using HAL_CAN_Init() function.
|
|
|
-
|
|
|
- (#) Transmit the desired CAN frame using HAL_CAN_Transmit() function.
|
|
|
-
|
|
|
- (#) Or transmit the desired CAN frame using HAL_CAN_Transmit_IT() function.
|
|
|
-
|
|
|
- (#) Receive a CAN frame using HAL_CAN_Receive() function.
|
|
|
-
|
|
|
- (#) Or receive a CAN frame using HAL_CAN_Receive_IT() function.
|
|
|
-
|
|
|
- *** Polling mode IO operation ***
|
|
|
- =================================
|
|
|
- [..]
|
|
|
- (+) Start the CAN peripheral transmission and wait the end of this operation
|
|
|
- using HAL_CAN_Transmit(), at this stage user can specify the value of timeout
|
|
|
- according to his end application
|
|
|
- (+) Start the CAN peripheral reception and wait the end of this operation
|
|
|
- using HAL_CAN_Receive(), at this stage user can specify the value of timeout
|
|
|
- according to his end application
|
|
|
-
|
|
|
- *** Interrupt mode IO operation ***
|
|
|
- ===================================
|
|
|
- [..]
|
|
|
- (+) Start the CAN peripheral transmission using HAL_CAN_Transmit_IT()
|
|
|
- (+) Start the CAN peripheral reception using HAL_CAN_Receive_IT()
|
|
|
- (+) Use HAL_CAN_IRQHandler() called under the used CAN Interrupt subroutine
|
|
|
- (+) At CAN end of transmission HAL_CAN_TxCpltCallback() function is executed and user can
|
|
|
- add his own code by customization of function pointer HAL_CAN_TxCpltCallback
|
|
|
- (+) In case of CAN Error, HAL_CAN_ErrorCallback() function is executed and user can
|
|
|
- add his own code by customization of function pointer HAL_CAN_ErrorCallback
|
|
|
-
|
|
|
- *** CAN HAL driver macros list ***
|
|
|
- =============================================
|
|
|
- [..]
|
|
|
- Below the list of most used macros in CAN HAL driver.
|
|
|
-
|
|
|
- (+) __HAL_CAN_ENABLE_IT: Enable the specified CAN interrupts
|
|
|
- (+) __HAL_CAN_DISABLE_IT: Disable the specified CAN interrupts
|
|
|
- (+) __HAL_CAN_GET_IT_SOURCE: Check if the specified CAN interrupt source is enabled or disabled
|
|
|
- (+) __HAL_CAN_CLEAR_FLAG: Clear the CAN's pending flags
|
|
|
- (+) __HAL_CAN_GET_FLAG: Get the selected CAN's flag status
|
|
|
-
|
|
|
- [..]
|
|
|
- (@) You can refer to the CAN HAL driver header file for more useful macros
|
|
|
-
|
|
|
+ [..]
|
|
|
+ (#) Initialize the CAN low level resources by implementing the
|
|
|
+ HAL_CAN_MspInit():
|
|
|
+ (++) Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE()
|
|
|
+ (++) Configure CAN pins
|
|
|
+ (+++) Enable the clock for the CAN GPIOs
|
|
|
+ (+++) Configure CAN pins as alternate function open-drain
|
|
|
+ (++) In case of using interrupts (e.g. HAL_CAN_ActivateNotification())
|
|
|
+ (+++) Configure the CAN interrupt priority using
|
|
|
+ HAL_NVIC_SetPriority()
|
|
|
+ (+++) Enable the CAN IRQ handler using HAL_NVIC_EnableIRQ()
|
|
|
+ (+++) In CAN IRQ handler, call HAL_CAN_IRQHandler()
|
|
|
+
|
|
|
+ (#) Initialize the CAN peripheral using HAL_CAN_Init() function. This
|
|
|
+ function resorts to HAL_CAN_MspInit() for low-level initialization.
|
|
|
+
|
|
|
+ (#) Configure the reception filters using the following configuration
|
|
|
+ functions:
|
|
|
+ (++) HAL_CAN_ConfigFilter()
|
|
|
+
|
|
|
+ (#) Start the CAN module using HAL_CAN_Start() function. At this level
|
|
|
+ the node is active on the bus: it receive messages, and can send
|
|
|
+ messages.
|
|
|
+
|
|
|
+ (#) To manage messages transmission, the following Tx control functions
|
|
|
+ can be used:
|
|
|
+ (++) HAL_CAN_AddTxMessage() to request transmission of a new
|
|
|
+ message.
|
|
|
+ (++) HAL_CAN_AbortTxRequest() to abort transmission of a pending
|
|
|
+ message.
|
|
|
+ (++) HAL_CAN_GetTxMailboxesFreeLevel() to get the number of free Tx
|
|
|
+ mailboxes.
|
|
|
+ (++) HAL_CAN_IsTxMessagePending() to check if a message is pending
|
|
|
+ in a Tx mailbox.
|
|
|
+ (++) HAL_CAN_GetTxTimestamp() to get the timestamp of Tx message
|
|
|
+ sent, if time triggered communication mode is enabled.
|
|
|
+
|
|
|
+ (#) When a message is received into the CAN Rx FIFOs, it can be retrieved
|
|
|
+ using the HAL_CAN_GetRxMessage() function. The function
|
|
|
+ HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message are
|
|
|
+ stored in the Rx Fifo.
|
|
|
+
|
|
|
+ (#) Calling the HAL_CAN_Stop() function stops the CAN module.
|
|
|
+
|
|
|
+ (#) The deinitialization is achieved with HAL_CAN_DeInit() function.
|
|
|
+
|
|
|
+
|
|
|
+ *** Polling mode operation ***
|
|
|
+ ==============================
|
|
|
+ [..]
|
|
|
+ (#) Reception:
|
|
|
+ (++) Monitor reception of message using HAL_CAN_GetRxFifoFillLevel()
|
|
|
+ until at least one message is received.
|
|
|
+ (++) Then get the message using HAL_CAN_GetRxMessage().
|
|
|
+
|
|
|
+ (#) Transmission:
|
|
|
+ (++) Monitor the Tx mailboxes availability until at least one Tx
|
|
|
+ mailbox is free, using HAL_CAN_GetTxMailboxesFreeLevel().
|
|
|
+ (++) Then request transmission of a message using
|
|
|
+ HAL_CAN_AddTxMessage().
|
|
|
+
|
|
|
+
|
|
|
+ *** Interrupt mode operation ***
|
|
|
+ ================================
|
|
|
+ [..]
|
|
|
+ (#) Notifications are activated using HAL_CAN_ActivateNotification()
|
|
|
+ function. Then, the process can be controlled through the
|
|
|
+ available user callbacks: HAL_CAN_xxxCallback(), using same APIs
|
|
|
+ HAL_CAN_GetRxMessage() and HAL_CAN_AddTxMessage().
|
|
|
+
|
|
|
+ (#) Notifications can be deactivated using
|
|
|
+ HAL_CAN_DeactivateNotification() function.
|
|
|
+
|
|
|
+ (#) Special care should be taken for CAN_IT_RX_FIFO0_MSG_PENDING and
|
|
|
+ CAN_IT_RX_FIFO1_MSG_PENDING notifications. These notifications trig
|
|
|
+ the callbacks HAL_CAN_RxFIFO0MsgPendingCallback() and
|
|
|
+ HAL_CAN_RxFIFO1MsgPendingCallback(). User has two possible options
|
|
|
+ here.
|
|
|
+ (++) Directly get the Rx message in the callback, using
|
|
|
+ HAL_CAN_GetRxMessage().
|
|
|
+ (++) Or deactivate the notification in the callback without
|
|
|
+ getting the Rx message. The Rx message can then be got later
|
|
|
+ using HAL_CAN_GetRxMessage(). Once the Rx message have been
|
|
|
+ read, the notification can be activated again.
|
|
|
+
|
|
|
+
|
|
|
+ *** Sleep mode ***
|
|
|
+ ==================
|
|
|
+ [..]
|
|
|
+ (#) The CAN peripheral can be put in sleep mode (low power), using
|
|
|
+ HAL_CAN_RequestSleep(). The sleep mode will be entered as soon as the
|
|
|
+ current CAN activity (transmission or reception of a CAN frame) will
|
|
|
+ be completed.
|
|
|
+
|
|
|
+ (#) A notification can be activated to be informed when the sleep mode
|
|
|
+ will be entered.
|
|
|
+
|
|
|
+ (#) It can be checked if the sleep mode is entered using
|
|
|
+ HAL_CAN_IsSleepActive().
|
|
|
+ Note that the CAN state (accessible from the API HAL_CAN_GetState())
|
|
|
+ is HAL_CAN_STATE_SLEEP_PENDING as soon as the sleep mode request is
|
|
|
+ submitted (the sleep mode is not yet entered), and become
|
|
|
+ HAL_CAN_STATE_SLEEP_ACTIVE when the sleep mode is effective.
|
|
|
+
|
|
|
+ (#) The wake-up from sleep mode can be trigged by two ways:
|
|
|
+ (++) Using HAL_CAN_WakeUp(). When returning from this function,
|
|
|
+ the sleep mode is exited (if return status is HAL_OK).
|
|
|
+ (++) When a start of Rx CAN frame is detected by the CAN peripheral,
|
|
|
+ if automatic wake up mode is enabled.
|
|
|
+
|
|
|
@endverbatim
|
|
|
-
|
|
|
******************************************************************************
|
|
|
* @attention
|
|
|
*
|
|
|
- * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
|
|
|
+ * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
|
|
*
|
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
|
* are permitted provided that the following conditions are met:
|
|
@@ -109,1590 +164,1836 @@
|
|
|
* @{
|
|
|
*/
|
|
|
|
|
|
+#if defined(CAN1)
|
|
|
+
|
|
|
/** @defgroup CAN CAN
|
|
|
* @brief CAN driver modules
|
|
|
* @{
|
|
|
*/
|
|
|
|
|
|
-#ifdef HAL_CAN_MODULE_ENABLED
|
|
|
-
|
|
|
-#if defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || \
|
|
|
- defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC)
|
|
|
-
|
|
|
+#ifdef HAL_CAN_MODULE_ENABLED
|
|
|
+
|
|
|
+#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
|
|
+ #error "The CAN driver cannot be used with its legacy, Please enable only one CAN module at once"
|
|
|
+#endif
|
|
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
/** @defgroup CAN_Private_Constants CAN Private Constants
|
|
|
* @{
|
|
|
*/
|
|
|
-#define CAN_TIMEOUT_VALUE 10U
|
|
|
+#define CAN_TIMEOUT_VALUE 10U
|
|
|
/**
|
|
|
* @}
|
|
|
*/
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
-/** @defgroup CAN_Private_Functions CAN Private Functions
|
|
|
- * @{
|
|
|
- */
|
|
|
-static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber);
|
|
|
-static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan);
|
|
|
-/**
|
|
|
- * @}
|
|
|
- */
|
|
|
-
|
|
|
/* Exported functions --------------------------------------------------------*/
|
|
|
+
|
|
|
/** @defgroup CAN_Exported_Functions CAN Exported Functions
|
|
|
* @{
|
|
|
*/
|
|
|
|
|
|
-/** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
|
|
|
- * @brief Initialization and Configuration functions
|
|
|
+/** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions
|
|
|
+ * @brief Initialization and Configuration functions
|
|
|
*
|
|
|
-@verbatim
|
|
|
+@verbatim
|
|
|
==============================================================================
|
|
|
##### Initialization and de-initialization functions #####
|
|
|
==============================================================================
|
|
|
[..] This section provides functions allowing to:
|
|
|
- (+) Initialize and configure the CAN.
|
|
|
- (+) De-initialize the CAN.
|
|
|
-
|
|
|
+ (+) HAL_CAN_Init : Initialize and configure the CAN.
|
|
|
+ (+) HAL_CAN_DeInit : De-initialize the CAN.
|
|
|
+ (+) HAL_CAN_MspInit : Initialize the CAN MSP.
|
|
|
+ (+) HAL_CAN_MspDeInit : DeInitialize the CAN MSP.
|
|
|
+
|
|
|
@endverbatim
|
|
|
* @{
|
|
|
*/
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* @brief Initializes the CAN peripheral according to the specified
|
|
|
* parameters in the CAN_InitStruct.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
* @retval HAL status
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
|
|
|
+HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */
|
|
|
- uint32_t tickstart = 0U;
|
|
|
- uint32_t tmp_mcr = 0U;
|
|
|
-
|
|
|
+ uint32_t tickstart;
|
|
|
+
|
|
|
/* Check CAN handle */
|
|
|
- if(hcan == NULL)
|
|
|
+ if (hcan == NULL)
|
|
|
{
|
|
|
- return HAL_ERROR;
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
|
|
|
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM));
|
|
|
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM));
|
|
|
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM));
|
|
|
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART));
|
|
|
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM));
|
|
|
- assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP));
|
|
|
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TimeTriggeredMode));
|
|
|
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoBusOff));
|
|
|
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoWakeUp));
|
|
|
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoRetransmission));
|
|
|
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ReceiveFifoLocked));
|
|
|
+ assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TransmitFifoPriority));
|
|
|
assert_param(IS_CAN_MODE(hcan->Init.Mode));
|
|
|
- assert_param(IS_CAN_SJW(hcan->Init.SJW));
|
|
|
- assert_param(IS_CAN_BS1(hcan->Init.BS1));
|
|
|
- assert_param(IS_CAN_BS2(hcan->Init.BS2));
|
|
|
+ assert_param(IS_CAN_SJW(hcan->Init.SyncJumpWidth));
|
|
|
+ assert_param(IS_CAN_BS1(hcan->Init.TimeSeg1));
|
|
|
+ assert_param(IS_CAN_BS2(hcan->Init.TimeSeg2));
|
|
|
assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler));
|
|
|
-
|
|
|
- if(hcan->State == HAL_CAN_STATE_RESET)
|
|
|
+
|
|
|
+ if (hcan->State == HAL_CAN_STATE_RESET)
|
|
|
{
|
|
|
- /* Allocate lock resource and initialize it */
|
|
|
- hcan->Lock = HAL_UNLOCKED;
|
|
|
- /* Init the low level hardware */
|
|
|
+ /* Init the low level hardware: CLOCK, NVIC */
|
|
|
HAL_CAN_MspInit(hcan);
|
|
|
}
|
|
|
-
|
|
|
- /* Initialize the CAN state*/
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY;
|
|
|
-
|
|
|
+
|
|
|
/* Exit from sleep mode */
|
|
|
CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
|
|
|
|
|
|
- /* Request initialisation */
|
|
|
- SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
|
|
|
-
|
|
|
- /* Get timeout */
|
|
|
- tickstart = HAL_GetTick();
|
|
|
-
|
|
|
- /* Wait the acknowledge */
|
|
|
- while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
|
|
|
- {
|
|
|
- if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
- {
|
|
|
- hcan->State= HAL_CAN_STATE_TIMEOUT;
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
- return HAL_TIMEOUT;
|
|
|
- }
|
|
|
- }
|
|
|
+ /* Get tick */
|
|
|
+ tickstart = HAL_GetTick();
|
|
|
|
|
|
- /* Check acknowledge */
|
|
|
- if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
|
|
|
+ /* Check Sleep mode leave acknowledge */
|
|
|
+ while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
|
|
|
{
|
|
|
- /* Set the time triggered communication mode */
|
|
|
- if (hcan->Init.TTCM == ENABLE)
|
|
|
- {
|
|
|
- SET_BIT(tmp_mcr, CAN_MCR_TTCM);
|
|
|
- }
|
|
|
- else
|
|
|
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
{
|
|
|
- CLEAR_BIT(tmp_mcr, CAN_MCR_TTCM);
|
|
|
- }
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
|
|
|
|
|
|
- /* Set the automatic bus-off management */
|
|
|
- if (hcan->Init.ABOM == ENABLE)
|
|
|
- {
|
|
|
- SET_BIT(tmp_mcr, CAN_MCR_ABOM);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CLEAR_BIT(tmp_mcr, CAN_MCR_ABOM);
|
|
|
- }
|
|
|
+ /* Change CAN state */
|
|
|
+ hcan->State = HAL_CAN_STATE_ERROR;
|
|
|
|
|
|
- /* Set the automatic wake-up mode */
|
|
|
- if (hcan->Init.AWUM == ENABLE)
|
|
|
- {
|
|
|
- SET_BIT(tmp_mcr, CAN_MCR_AWUM);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CLEAR_BIT(tmp_mcr, CAN_MCR_AWUM);
|
|
|
- }
|
|
|
- /* Set the no automatic retransmission */
|
|
|
- if (hcan->Init.NART == ENABLE)
|
|
|
- {
|
|
|
- SET_BIT(tmp_mcr, CAN_MCR_NART);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CLEAR_BIT(tmp_mcr, CAN_MCR_NART);
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- /* Set the receive FIFO locked mode */
|
|
|
- if (hcan->Init.RFLM == ENABLE)
|
|
|
- {
|
|
|
- SET_BIT(tmp_mcr, CAN_MCR_RFLM);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CLEAR_BIT(tmp_mcr, CAN_MCR_RFLM);
|
|
|
- }
|
|
|
- /* Set the transmit FIFO priority */
|
|
|
- if (hcan->Init.TXFP == ENABLE)
|
|
|
- {
|
|
|
- SET_BIT(tmp_mcr, CAN_MCR_TXFP);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CLEAR_BIT(tmp_mcr, CAN_MCR_TXFP);
|
|
|
- }
|
|
|
-
|
|
|
- /* Update register MCR */
|
|
|
- MODIFY_REG(hcan->Instance->MCR,
|
|
|
- CAN_MCR_TTCM |
|
|
|
- CAN_MCR_ABOM |
|
|
|
- CAN_MCR_AWUM |
|
|
|
- CAN_MCR_NART |
|
|
|
- CAN_MCR_RFLM |
|
|
|
- CAN_MCR_TXFP,
|
|
|
- tmp_mcr);
|
|
|
-
|
|
|
- /* Set the bit timing register */
|
|
|
- WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
|
|
|
- hcan->Init.SJW |
|
|
|
- hcan->Init.BS1 |
|
|
|
- hcan->Init.BS2 |
|
|
|
- (hcan->Init.Prescaler - 1U)));
|
|
|
+ /* Request initialisation */
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
|
|
|
|
|
|
- /* Request leave initialisation */
|
|
|
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
|
|
|
+ /* Get tick */
|
|
|
+ tickstart = HAL_GetTick();
|
|
|
|
|
|
- /* Get timeout */
|
|
|
- tickstart = HAL_GetTick();
|
|
|
-
|
|
|
- /* Wait the acknowledge */
|
|
|
- while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
|
|
|
+ /* Wait initialisation acknowledge */
|
|
|
+ while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
|
|
|
+ {
|
|
|
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
{
|
|
|
- if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
- {
|
|
|
- hcan->State= HAL_CAN_STATE_TIMEOUT;
|
|
|
-
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
|
|
|
|
|
|
- return HAL_TIMEOUT;
|
|
|
- }
|
|
|
- }
|
|
|
+ /* Change CAN state */
|
|
|
+ hcan->State = HAL_CAN_STATE_ERROR;
|
|
|
|
|
|
- /* Check acknowledged */
|
|
|
- if(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
|
|
|
- {
|
|
|
- status = CAN_INITSTATUS_SUCCESS;
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- if(status == CAN_INITSTATUS_SUCCESS)
|
|
|
+
|
|
|
+ /* Set the time triggered communication mode */
|
|
|
+ if (hcan->Init.TimeTriggeredMode == ENABLE)
|
|
|
{
|
|
|
- /* Set CAN error code to none */
|
|
|
- hcan->ErrorCode = HAL_CAN_ERROR_NONE;
|
|
|
-
|
|
|
- /* Initialize the CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
-
|
|
|
- /* Return function status */
|
|
|
- return HAL_OK;
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- /* Initialize the CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_ERROR;
|
|
|
-
|
|
|
- /* Return function status */
|
|
|
- return HAL_ERROR;
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * @brief Configures the CAN reception filter according to the specified
|
|
|
- * parameters in the CAN_FilterInitStruct.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
- * @param sFilterConfig: pointer to a CAN_FilterConfTypeDef structure that
|
|
|
- * contains the filter configuration information.
|
|
|
- * @retval None
|
|
|
- */
|
|
|
-HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef* hcan, CAN_FilterConfTypeDef* sFilterConfig)
|
|
|
-{
|
|
|
- uint32_t filternbrbitpos = 0U;
|
|
|
-
|
|
|
- /* Prevent unused argument(s) compilation warning */
|
|
|
- UNUSED(hcan);
|
|
|
|
|
|
- /* Check the parameters */
|
|
|
- assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
|
|
|
- assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
|
|
|
- assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
|
|
|
- assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
|
|
|
- assert_param(IS_FUNCTIONAL_STATE(sFilterConfig->FilterActivation));
|
|
|
- assert_param(IS_CAN_BANKNUMBER(sFilterConfig->BankNumber));
|
|
|
-
|
|
|
- filternbrbitpos = (1U) << sFilterConfig->FilterNumber;
|
|
|
-
|
|
|
- /* Initialisation mode for the filter */
|
|
|
- /* Select the start slave bank */
|
|
|
- MODIFY_REG(hcan->Instance->FMR ,
|
|
|
- CAN_FMR_CAN2SB ,
|
|
|
- CAN_FMR_FINIT |
|
|
|
- (uint32_t)(sFilterConfig->BankNumber << 8U) );
|
|
|
-
|
|
|
- /* Filter Deactivation */
|
|
|
- CLEAR_BIT(hcan->Instance->FA1R, filternbrbitpos);
|
|
|
-
|
|
|
- /* Filter Scale */
|
|
|
- if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
|
|
|
+ /* Set the automatic bus-off management */
|
|
|
+ if (hcan->Init.AutoBusOff == ENABLE)
|
|
|
{
|
|
|
- /* 16-bit scale for the filter */
|
|
|
- CLEAR_BIT(hcan->Instance->FS1R, filternbrbitpos);
|
|
|
-
|
|
|
- /* First 16-bit identifier and First 16-bit mask */
|
|
|
- /* Or First 16-bit identifier and Second 16-bit identifier */
|
|
|
- hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
|
|
|
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
|
|
|
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
|
|
|
-
|
|
|
- /* Second 16-bit identifier and Second 16-bit mask */
|
|
|
- /* Or Third 16-bit identifier and Fourth 16-bit identifier */
|
|
|
- hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
|
|
|
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
|
|
|
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
|
|
|
}
|
|
|
|
|
|
- if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
|
|
|
+ /* Set the automatic wake-up mode */
|
|
|
+ if (hcan->Init.AutoWakeUp == ENABLE)
|
|
|
{
|
|
|
- /* 32-bit scale for the filter */
|
|
|
- SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
|
|
|
- /* 32-bit identifier or First 32-bit identifier */
|
|
|
- hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 =
|
|
|
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
|
|
|
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
|
|
|
- /* 32-bit mask or Second 32-bit identifier */
|
|
|
- hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR2 =
|
|
|
- ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
|
|
|
- (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
|
|
|
}
|
|
|
|
|
|
- /* Filter Mode */
|
|
|
- if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
|
|
|
+ /* Set the automatic retransmission */
|
|
|
+ if (hcan->Init.AutoRetransmission == ENABLE)
|
|
|
{
|
|
|
- /*Id/Mask mode for the filter*/
|
|
|
- CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART);
|
|
|
}
|
|
|
- else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
|
|
|
+ else
|
|
|
{
|
|
|
- /*Identifier list mode for the filter*/
|
|
|
- SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_NART);
|
|
|
}
|
|
|
|
|
|
- /* Filter FIFO assignment */
|
|
|
- if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
|
|
|
+ /* Set the receive FIFO locked mode */
|
|
|
+ if (hcan->Init.ReceiveFifoLocked == ENABLE)
|
|
|
{
|
|
|
- /* FIFO 0 assignation for the filter */
|
|
|
- CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- /* FIFO 1 assignation for the filter */
|
|
|
- SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set the transmit FIFO priority */
|
|
|
+ if (hcan->Init.TransmitFifoPriority == ENABLE)
|
|
|
+ {
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
|
|
|
}
|
|
|
-
|
|
|
- /* Filter activation */
|
|
|
- if (sFilterConfig->FilterActivation == ENABLE)
|
|
|
+ else
|
|
|
{
|
|
|
- SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
|
|
|
}
|
|
|
|
|
|
- /* Leave the initialisation mode for the filter */
|
|
|
- CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
|
|
|
-
|
|
|
+ /* Set the bit timing register */
|
|
|
+ WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode |
|
|
|
+ hcan->Init.SyncJumpWidth |
|
|
|
+ hcan->Init.TimeSeg1 |
|
|
|
+ hcan->Init.TimeSeg2 |
|
|
|
+ (hcan->Init.Prescaler - 1U)));
|
|
|
+
|
|
|
+ /* Initialize the error code */
|
|
|
+ hcan->ErrorCode = HAL_CAN_ERROR_NONE;
|
|
|
+
|
|
|
+ /* Initialize the CAN state */
|
|
|
+ hcan->State = HAL_CAN_STATE_READY;
|
|
|
+
|
|
|
/* Return function status */
|
|
|
return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Deinitializes the CANx peripheral registers to their default reset values.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
+ * @brief Deinitializes the CAN peripheral registers to their default
|
|
|
+ * reset values.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
* @retval HAL status
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef* hcan)
|
|
|
+HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
/* Check CAN handle */
|
|
|
- if(hcan == NULL)
|
|
|
+ if (hcan == NULL)
|
|
|
{
|
|
|
- return HAL_ERROR;
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance));
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY;
|
|
|
-
|
|
|
- /* DeInit the low level hardware */
|
|
|
+
|
|
|
+ /* Stop the CAN module */
|
|
|
+ (void)HAL_CAN_Stop(hcan);
|
|
|
+
|
|
|
+ /* DeInit the low level hardware: CLOCK, NVIC */
|
|
|
HAL_CAN_MspDeInit(hcan);
|
|
|
-
|
|
|
+
|
|
|
+ /* Reset the CAN peripheral */
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_RESET);
|
|
|
+
|
|
|
+ /* Reset the CAN ErrorCode */
|
|
|
+ hcan->ErrorCode = HAL_CAN_ERROR_NONE;
|
|
|
+
|
|
|
/* Change CAN state */
|
|
|
hcan->State = HAL_CAN_STATE_RESET;
|
|
|
|
|
|
- /* Release Lock */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
-
|
|
|
/* Return function status */
|
|
|
return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Initializes the CAN MSP.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
* @retval None
|
|
|
*/
|
|
|
-__weak void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
|
|
|
+__weak void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
UNUSED(hcan);
|
|
|
+
|
|
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
- the HAL_CAN_MspInit can be implemented in the user file
|
|
|
- */
|
|
|
+ the HAL_CAN_MspInit could be implemented in the user file
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief DeInitializes the CAN MSP.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
* @retval None
|
|
|
*/
|
|
|
-__weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
|
|
|
+__weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
UNUSED(hcan);
|
|
|
+
|
|
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
- the HAL_CAN_MspDeInit can be implemented in the user file
|
|
|
- */
|
|
|
+ the HAL_CAN_MspDeInit could be implemented in the user file
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* @}
|
|
|
*/
|
|
|
|
|
|
-/** @defgroup CAN_Exported_Functions_Group2 Input and Output operation functions
|
|
|
- * @brief I/O operation functions
|
|
|
- *
|
|
|
-@verbatim
|
|
|
+/** @defgroup CAN_Exported_Functions_Group2 Configuration functions
|
|
|
+ * @brief Configuration functions.
|
|
|
+ *
|
|
|
+@verbatim
|
|
|
==============================================================================
|
|
|
- ##### IO operation functions #####
|
|
|
+ ##### Configuration functions #####
|
|
|
==============================================================================
|
|
|
[..] This section provides functions allowing to:
|
|
|
- (+) Transmit a CAN frame message.
|
|
|
- (+) Receive a CAN frame message.
|
|
|
- (+) Enter CAN peripheral in sleep mode.
|
|
|
- (+) Wake up the CAN peripheral from sleep mode.
|
|
|
-
|
|
|
+ (+) HAL_CAN_ConfigFilter : Configure the CAN reception filters
|
|
|
+
|
|
|
@endverbatim
|
|
|
* @{
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
- * @brief Initiates and transmits a CAN frame message.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
- * @param Timeout: Specify Timeout value
|
|
|
- * @retval HAL status
|
|
|
+ * @brief Configures the CAN reception filter according to the specified
|
|
|
+ * parameters in the CAN_FilterInitStruct.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @param sFilterConfig pointer to a CAN_FilterTypeDef structure that
|
|
|
+ * contains the filter configuration information.
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
|
|
|
+HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, CAN_FilterTypeDef *sFilterConfig)
|
|
|
{
|
|
|
- uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
|
|
|
- uint32_t tickstart = 0U;
|
|
|
-
|
|
|
- /* Check the parameters */
|
|
|
- assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
|
|
|
- assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
|
|
|
- assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
|
|
|
+ uint32_t filternbrbitpos;
|
|
|
+ CAN_TypeDef *can_ip = hcan->Instance;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
|
|
|
- if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
|
|
|
- ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
|
|
|
- ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- /* Process locked */
|
|
|
- __HAL_LOCK(hcan);
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- switch(hcan->State)
|
|
|
+ /* Check the parameters */
|
|
|
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdHigh));
|
|
|
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdLow));
|
|
|
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdHigh));
|
|
|
+ assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdLow));
|
|
|
+ assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode));
|
|
|
+ assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale));
|
|
|
+ assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment));
|
|
|
+ assert_param(IS_CAN_FILTER_ACTIVATION(sFilterConfig->FilterActivation));
|
|
|
+
|
|
|
+#if defined(CAN2)
|
|
|
+ /* CAN1 and CAN2 are dual instances with 28 common filters banks */
|
|
|
+ /* Select master instance to access the filter banks */
|
|
|
+ can_ip = CAN1;
|
|
|
+
|
|
|
+ /* Check the parameters */
|
|
|
+ assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->FilterBank));
|
|
|
+ assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->SlaveStartFilterBank));
|
|
|
+#else
|
|
|
+ /* CAN1 is single instance with 14 dedicated filters banks */
|
|
|
+
|
|
|
+ /* Check the parameters */
|
|
|
+ assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank));
|
|
|
+#endif
|
|
|
+
|
|
|
+ /* Initialisation mode for the filter */
|
|
|
+ SET_BIT(can_ip->FMR, CAN_FMR_FINIT);
|
|
|
+
|
|
|
+#if defined(CAN2)
|
|
|
+ /* Select the start filter number of CAN2 slave instance */
|
|
|
+ CLEAR_BIT(can_ip->FMR, CAN_FMR_CAN2SB);
|
|
|
+ SET_BIT(can_ip->FMR, sFilterConfig->SlaveStartFilterBank << CAN_FMR_CAN2SB_Pos);
|
|
|
+
|
|
|
+#endif
|
|
|
+ /* Convert filter number into bit position */
|
|
|
+ filternbrbitpos = (uint32_t)1 << (sFilterConfig->FilterBank & 0x1FU);
|
|
|
+
|
|
|
+ /* Filter Deactivation */
|
|
|
+ CLEAR_BIT(can_ip->FA1R, filternbrbitpos);
|
|
|
+
|
|
|
+ /* Filter Scale */
|
|
|
+ if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT)
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_READY */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX;
|
|
|
- break;
|
|
|
+ /* 16-bit scale for the filter */
|
|
|
+ CLEAR_BIT(can_ip->FS1R, filternbrbitpos);
|
|
|
+
|
|
|
+ /* First 16-bit identifier and First 16-bit mask */
|
|
|
+ /* Or First 16-bit identifier and Second 16-bit identifier */
|
|
|
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
|
|
|
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
|
|
|
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
|
|
|
+
|
|
|
+ /* Second 16-bit identifier and Second 16-bit mask */
|
|
|
+ /* Or Third 16-bit identifier and Fourth 16-bit identifier */
|
|
|
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
|
|
|
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
|
|
|
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
|
|
|
}
|
|
|
|
|
|
- /* Select one empty transmit mailbox */
|
|
|
- if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
|
|
|
+ if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
|
|
|
{
|
|
|
- transmitmailbox = CAN_TXMAILBOX_0;
|
|
|
+ /* 32-bit scale for the filter */
|
|
|
+ SET_BIT(can_ip->FS1R, filternbrbitpos);
|
|
|
+
|
|
|
+ /* 32-bit identifier or First 32-bit identifier */
|
|
|
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 =
|
|
|
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
|
|
|
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow);
|
|
|
+
|
|
|
+ /* 32-bit mask or Second 32-bit identifier */
|
|
|
+ can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 =
|
|
|
+ ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
|
|
|
+ (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
|
|
|
}
|
|
|
- else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
|
|
|
+
|
|
|
+ /* Filter Mode */
|
|
|
+ if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
|
|
|
{
|
|
|
- transmitmailbox = CAN_TXMAILBOX_1;
|
|
|
+ /* Id/Mask mode for the filter*/
|
|
|
+ CLEAR_BIT(can_ip->FM1R, filternbrbitpos);
|
|
|
}
|
|
|
- else
|
|
|
+ else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
|
|
|
{
|
|
|
- transmitmailbox = CAN_TXMAILBOX_2;
|
|
|
+ /* Identifier list mode for the filter*/
|
|
|
+ SET_BIT(can_ip->FM1R, filternbrbitpos);
|
|
|
}
|
|
|
|
|
|
- /* Set up the Id */
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
|
|
|
- if (hcan->pTxMsg->IDE == CAN_ID_STD)
|
|
|
+ /* Filter FIFO assignment */
|
|
|
+ if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
|
|
|
{
|
|
|
- assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) |
|
|
|
- hcan->pTxMsg->RTR);
|
|
|
+ /* FIFO 0 assignation for the filter */
|
|
|
+ CLEAR_BIT(can_ip->FFA1R, filternbrbitpos);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) |
|
|
|
- hcan->pTxMsg->IDE |
|
|
|
- hcan->pTxMsg->RTR);
|
|
|
+ /* FIFO 1 assignation for the filter */
|
|
|
+ SET_BIT(can_ip->FFA1R, filternbrbitpos);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Filter activation */
|
|
|
+ if (sFilterConfig->FilterActivation == CAN_FILTER_ENABLE)
|
|
|
+ {
|
|
|
+ SET_BIT(can_ip->FA1R, filternbrbitpos);
|
|
|
}
|
|
|
|
|
|
- /* Set up the DLC */
|
|
|
- hcan->pTxMsg->DLC &= (uint8_t)0x0000000F;
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
|
|
|
-
|
|
|
- /* Set up the data field */
|
|
|
- WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_Pos));
|
|
|
- WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_Pos));
|
|
|
- /* Request transmission */
|
|
|
- SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
|
|
|
+ /* Leave the initialisation mode for the filter */
|
|
|
+ CLEAR_BIT(can_ip->FMR, CAN_FMR_FINIT);
|
|
|
+
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @}
|
|
|
+ */
|
|
|
+
|
|
|
+/** @defgroup CAN_Exported_Functions_Group3 Control functions
|
|
|
+ * @brief Control functions
|
|
|
+ *
|
|
|
+@verbatim
|
|
|
+ ==============================================================================
|
|
|
+ ##### Control functions #####
|
|
|
+ ==============================================================================
|
|
|
+ [..] This section provides functions allowing to:
|
|
|
+ (+) HAL_CAN_Start : Start the CAN module
|
|
|
+ (+) HAL_CAN_Stop : Stop the CAN module
|
|
|
+ (+) HAL_CAN_RequestSleep : Request sleep mode entry.
|
|
|
+ (+) HAL_CAN_WakeUp : Wake up from sleep mode.
|
|
|
+ (+) HAL_CAN_IsSleepActive : Check is sleep mode is active.
|
|
|
+ (+) HAL_CAN_AddTxMessage : Add a message to the Tx mailboxes
|
|
|
+ and activate the corresponding
|
|
|
+ transmission request
|
|
|
+ (+) HAL_CAN_AbortTxRequest : Abort transmission request
|
|
|
+ (+) HAL_CAN_GetTxMailboxesFreeLevel : Return Tx mailboxes free level
|
|
|
+ (+) HAL_CAN_IsTxMessagePending : Check if a transmission request is
|
|
|
+ pending on the selected Tx mailbox
|
|
|
+ (+) HAL_CAN_GetRxMessage : Get a CAN frame from the Rx FIFO
|
|
|
+ (+) HAL_CAN_GetRxFifoFillLevel : Return Rx FIFO fill level
|
|
|
+
|
|
|
+@endverbatim
|
|
|
+ * @{
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Start the CAN module.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval HAL status
|
|
|
+ */
|
|
|
+HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ uint32_t tickstart;
|
|
|
+
|
|
|
+ if (hcan->State == HAL_CAN_STATE_READY)
|
|
|
+ {
|
|
|
+ /* Change CAN peripheral state */
|
|
|
+ hcan->State = HAL_CAN_STATE_LISTENING;
|
|
|
+
|
|
|
+ /* Request leave initialisation */
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
|
|
|
|
|
|
/* Get tick */
|
|
|
tickstart = HAL_GetTick();
|
|
|
|
|
|
- /* Check End of transmission flag */
|
|
|
- while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
|
|
|
+ /* Wait the acknowledge */
|
|
|
+ while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U)
|
|
|
{
|
|
|
/* Check for the Timeout */
|
|
|
- if(Timeout != HAL_MAX_DELAY)
|
|
|
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
{
|
|
|
- if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
|
|
|
- {
|
|
|
- hcan->State = HAL_CAN_STATE_TIMEOUT;
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
|
|
|
|
|
|
- /* Cancel transmission */
|
|
|
- __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
|
|
|
+ /* Change CAN state */
|
|
|
+ hcan->State = HAL_CAN_STATE_ERROR;
|
|
|
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
- return HAL_TIMEOUT;
|
|
|
- }
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
}
|
|
|
- /* Change CAN state */
|
|
|
- switch(hcan->State)
|
|
|
- {
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_BUSY_TX */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
- break;
|
|
|
- }
|
|
|
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
+ /* Reset the CAN ErrorCode */
|
|
|
+ hcan->ErrorCode = HAL_CAN_ERROR_NONE;
|
|
|
|
|
|
/* Return function status */
|
|
|
return HAL_OK;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- /* Change CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_ERROR;
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_READY;
|
|
|
|
|
|
- /* Return function status */
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Initiates and transmits a CAN frame message.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
+ * @brief Stop the CAN module and enable access to configuration registers.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
* @retval HAL status
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
|
|
|
+HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
|
|
|
+ uint32_t tickstart;
|
|
|
|
|
|
- /* Check the parameters */
|
|
|
- assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE));
|
|
|
- assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR));
|
|
|
- assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC));
|
|
|
-
|
|
|
- if(((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) || \
|
|
|
- ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) || \
|
|
|
- ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2))
|
|
|
+ if (hcan->State == HAL_CAN_STATE_LISTENING)
|
|
|
{
|
|
|
- /* Process Locked */
|
|
|
- __HAL_LOCK(hcan);
|
|
|
-
|
|
|
- /* Select one empty transmit mailbox */
|
|
|
- if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
|
|
|
- {
|
|
|
- transmitmailbox = CAN_TXMAILBOX_0;
|
|
|
- }
|
|
|
- else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
|
|
|
- {
|
|
|
- transmitmailbox = CAN_TXMAILBOX_1;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- transmitmailbox = CAN_TXMAILBOX_2;
|
|
|
- }
|
|
|
+ /* Request initialisation */
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
|
|
|
|
|
|
- /* Set up the Id */
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
|
|
|
- if(hcan->pTxMsg->IDE == CAN_ID_STD)
|
|
|
- {
|
|
|
- assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << CAN_TI0R_STID_Pos) | \
|
|
|
- hcan->pTxMsg->RTR);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId));
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
|
|
|
- hcan->pTxMsg->IDE |
|
|
|
- hcan->pTxMsg->RTR);
|
|
|
- }
|
|
|
+ /* Get tick */
|
|
|
+ tickstart = HAL_GetTick();
|
|
|
|
|
|
- /* Set up the DLC */
|
|
|
- hcan->pTxMsg->DLC &= (uint8_t)0x0000000FU;
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= 0xFFFFFFF0U;
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
|
|
|
-
|
|
|
- /* Set up the data field */
|
|
|
- WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3U] << CAN_TDL0R_DATA3_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[2U] << CAN_TDL0R_DATA2_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[1U] << CAN_TDL0R_DATA1_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[0U] << CAN_TDL0R_DATA0_Pos));
|
|
|
- WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7U] << CAN_TDL0R_DATA3_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[6U] << CAN_TDL0R_DATA2_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[5U] << CAN_TDL0R_DATA1_Pos) |
|
|
|
- ((uint32_t)hcan->pTxMsg->Data[4U] << CAN_TDL0R_DATA0_Pos));
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- switch(hcan->State)
|
|
|
+ /* Wait the acknowledge */
|
|
|
+ while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U)
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_READY */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX;
|
|
|
- break;
|
|
|
+ /* Check for the Timeout */
|
|
|
+ if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
|
|
|
+
|
|
|
+ /* Change CAN state */
|
|
|
+ hcan->State = HAL_CAN_STATE_ERROR;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /* Set CAN error code to none */
|
|
|
- hcan->ErrorCode = HAL_CAN_ERROR_NONE;
|
|
|
+ /* Exit from sleep mode */
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
|
|
|
+
|
|
|
+ /* Change CAN peripheral state */
|
|
|
+ hcan->State = HAL_CAN_STATE_READY;
|
|
|
|
|
|
- /* Process Unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
-
|
|
|
- /* Request transmission */
|
|
|
- hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
|
|
|
-
|
|
|
- /* Enable interrupts: */
|
|
|
- /* - Enable Error warning Interrupt */
|
|
|
- /* - Enable Error passive Interrupt */
|
|
|
- /* - Enable Bus-off Interrupt */
|
|
|
- /* - Enable Last error code Interrupt */
|
|
|
- /* - Enable Error Interrupt */
|
|
|
- /* - Enable Transmit mailbox empty Interrupt */
|
|
|
- __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
|
|
|
- CAN_IT_EPV |
|
|
|
- CAN_IT_BOF |
|
|
|
- CAN_IT_LEC |
|
|
|
- CAN_IT_ERR |
|
|
|
- CAN_IT_TME );
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- /* Change CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_ERROR;
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_STARTED;
|
|
|
|
|
|
- /* Return function status */
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
-
|
|
|
- return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Receives a correct CAN frame.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
- * @param FIFONumber: FIFO Number value
|
|
|
- * @param Timeout: Specify Timeout value
|
|
|
- * @retval HAL status
|
|
|
+ * @brief Request the sleep mode (low power) entry.
|
|
|
+ * When returning from this function, Sleep mode will be entered
|
|
|
+ * as soon as the current CAN activity (transmission or reception
|
|
|
+ * of a CAN frame) has been completed.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval HAL status.
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
|
|
|
+HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- uint32_t tickstart = 0U;
|
|
|
- CanRxMsgTypeDef* pRxMsg = NULL;
|
|
|
-
|
|
|
- /* Check the parameters */
|
|
|
- assert_param(IS_CAN_FIFO(FIFONumber));
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
|
|
|
- /* Check if CAN state is not busy for RX FIFO0 */
|
|
|
- if ((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- return HAL_BUSY;
|
|
|
- }
|
|
|
+ /* Request Sleep mode */
|
|
|
+ SET_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
|
|
|
|
|
|
- /* Check if CAN state is not busy for RX FIFO1 */
|
|
|
- if ((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- return HAL_BUSY;
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
+
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- /* Process locked */
|
|
|
- __HAL_LOCK(hcan);
|
|
|
+/**
|
|
|
+ * @brief Wake up from sleep mode.
|
|
|
+ * When returning with HAL_OK status from this function, Sleep mode
|
|
|
+ * is exited.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval HAL status.
|
|
|
+ */
|
|
|
+HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ __IO uint32_t count = 0;
|
|
|
+ uint32_t timeout = 1000000U;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
|
|
|
- /* Change CAN state */
|
|
|
- if (FIFONumber == CAN_FIFO0)
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- switch(hcan->State)
|
|
|
+ /* Wake up request */
|
|
|
+ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
|
|
|
+
|
|
|
+ /* Wait sleep mode is exited */
|
|
|
+ do
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_TX):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_READY */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
- {
|
|
|
- switch(hcan->State)
|
|
|
- {
|
|
|
- case(HAL_CAN_STATE_BUSY_TX):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_READY */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX1;
|
|
|
- break;
|
|
|
+ /* Increment counter */
|
|
|
+ count++;
|
|
|
+
|
|
|
+ /* Check if timeout is reached */
|
|
|
+ if (count > timeout)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
}
|
|
|
+ while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U);
|
|
|
+
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
}
|
|
|
- /* Get tick */
|
|
|
- tickstart = HAL_GetTick();
|
|
|
-
|
|
|
- /* Check pending message */
|
|
|
- while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Check is sleep mode is active.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval Status
|
|
|
+ * - 0 : Sleep mode is not active.
|
|
|
+ * - 1 : Sleep mode is active.
|
|
|
+ */
|
|
|
+uint32_t HAL_CAN_IsSleepActive(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ uint32_t status = 0U;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- /* Check for the Timeout */
|
|
|
- if(Timeout != HAL_MAX_DELAY)
|
|
|
+ /* Check Sleep mode */
|
|
|
+ if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
|
|
|
{
|
|
|
- if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
|
|
|
- {
|
|
|
- hcan->State = HAL_CAN_STATE_TIMEOUT;
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
- return HAL_TIMEOUT;
|
|
|
- }
|
|
|
+ status = 1U;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* Set RxMsg pointer */
|
|
|
- if(FIFONumber == CAN_FIFO0)
|
|
|
+ /* Return function status */
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Add a message to the first free Tx mailbox and activate the
|
|
|
+ * corresponding transmission request.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @param pHeader pointer to a CAN_TxHeaderTypeDef structure.
|
|
|
+ * @param aData array containing the payload of the Tx frame.
|
|
|
+ * @param pTxMailbox pointer to a variable where the function will return
|
|
|
+ * the TxMailbox used to store the Tx message.
|
|
|
+ * This parameter can be a value of @arg CAN_Tx_Mailboxes.
|
|
|
+ * @retval HAL status
|
|
|
+ */
|
|
|
+HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox)
|
|
|
+{
|
|
|
+ uint32_t transmitmailbox;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+ uint32_t tsr = READ_REG(hcan->Instance->TSR);
|
|
|
+
|
|
|
+ /* Check the parameters */
|
|
|
+ assert_param(IS_CAN_IDTYPE(pHeader->IDE));
|
|
|
+ assert_param(IS_CAN_RTR(pHeader->RTR));
|
|
|
+ assert_param(IS_CAN_DLC(pHeader->DLC));
|
|
|
+ if (pHeader->IDE == CAN_ID_STD)
|
|
|
{
|
|
|
- pRxMsg = hcan->pRxMsg;
|
|
|
+ assert_param(IS_CAN_STDID(pHeader->StdId));
|
|
|
}
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
+ else
|
|
|
{
|
|
|
- pRxMsg = hcan->pRx1Msg;
|
|
|
+ assert_param(IS_CAN_EXTID(pHeader->ExtId));
|
|
|
}
|
|
|
+ assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime));
|
|
|
|
|
|
- /* Get the Id */
|
|
|
- pRxMsg->IDE = (uint8_t)CAN_ID_EXT & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
|
|
|
- if (pRxMsg->IDE == CAN_ID_STD)
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
|
|
|
+ /* Check that all the Tx mailboxes are not full */
|
|
|
+ if (((tsr & CAN_TSR_TME0) != 0U) ||
|
|
|
+ ((tsr & CAN_TSR_TME1) != 0U) ||
|
|
|
+ ((tsr & CAN_TSR_TME2) != 0U))
|
|
|
+ {
|
|
|
+ /* Select an empty transmit mailbox */
|
|
|
+ transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos;
|
|
|
+
|
|
|
+ /* Check transmit mailbox value */
|
|
|
+ if (transmitmailbox > 2U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_INTERNAL;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Store the Tx mailbox */
|
|
|
+ *pTxMailbox = (uint32_t)1 << transmitmailbox;
|
|
|
+
|
|
|
+ /* Set up the Id */
|
|
|
+ if (pHeader->IDE == CAN_ID_STD)
|
|
|
+ {
|
|
|
+ hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) |
|
|
|
+ pHeader->RTR);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) |
|
|
|
+ pHeader->IDE |
|
|
|
+ pHeader->RTR);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set up the DLC */
|
|
|
+ hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC);
|
|
|
+
|
|
|
+ /* Set up the Transmit Global Time mode */
|
|
|
+ if (pHeader->TransmitGlobalTime == ENABLE)
|
|
|
+ {
|
|
|
+ SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set up the data field */
|
|
|
+ WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR,
|
|
|
+ ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) |
|
|
|
+ ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) |
|
|
|
+ ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) |
|
|
|
+ ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos));
|
|
|
+ WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR,
|
|
|
+ ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) |
|
|
|
+ ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) |
|
|
|
+ ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) |
|
|
|
+ ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos));
|
|
|
+
|
|
|
+ /* Request transmission */
|
|
|
+ SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
|
|
|
+
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
-
|
|
|
- pRxMsg->RTR = (uint8_t)CAN_RTR_REMOTE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
|
|
|
- /* Get the DLC */
|
|
|
- pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
|
|
|
- /* Get the FMI */
|
|
|
- pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
|
|
|
- /* Get the FIFONumber */
|
|
|
- pRxMsg->FIFONumber = FIFONumber;
|
|
|
- /* Get the data field */
|
|
|
- pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
|
|
|
- pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
|
|
|
- pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
|
|
|
- pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
|
|
|
- pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
|
|
|
- pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
|
|
|
- pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
|
|
|
- pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
|
|
|
-
|
|
|
- /* Release the FIFO */
|
|
|
- if(FIFONumber == CAN_FIFO0)
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Abort transmission requests
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @param TxMailboxes List of the Tx Mailboxes to abort.
|
|
|
+ * This parameter can be any combination of @arg CAN_Tx_Mailboxes.
|
|
|
+ * @retval HAL status
|
|
|
+ */
|
|
|
+HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
|
|
|
+{
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ /* Check function parameters */
|
|
|
+ assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- /* Release FIFO0 */
|
|
|
- __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
|
|
|
+ /* Check Tx Mailbox 0 */
|
|
|
+ if ((TxMailboxes & CAN_TX_MAILBOX0) != 0U)
|
|
|
+ {
|
|
|
+ /* Add cancellation request for Tx Mailbox 0 */
|
|
|
+ SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check Tx Mailbox 1 */
|
|
|
+ if ((TxMailboxes & CAN_TX_MAILBOX1) != 0U)
|
|
|
+ {
|
|
|
+ /* Add cancellation request for Tx Mailbox 1 */
|
|
|
+ SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check Tx Mailbox 2 */
|
|
|
+ if ((TxMailboxes & CAN_TX_MAILBOX2) != 0U)
|
|
|
+ {
|
|
|
+ /* Add cancellation request for Tx Mailbox 2 */
|
|
|
+ SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
}
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
+ else
|
|
|
{
|
|
|
- /* Release FIFO1 */
|
|
|
- __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- if (FIFONumber == CAN_FIFO0)
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Return Tx Mailboxes free level: number of free Tx Mailboxes.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval Number of free Tx Mailboxes.
|
|
|
+ */
|
|
|
+uint32_t HAL_CAN_GetTxMailboxesFreeLevel(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ uint32_t freelevel = 0U;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- switch(hcan->State)
|
|
|
+ /* Check Tx Mailbox 0 status */
|
|
|
+ if ((hcan->Instance->TSR & CAN_TSR_TME0) != 0U)
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_BUSY_RX0 */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
- break;
|
|
|
+ freelevel++;
|
|
|
}
|
|
|
- }
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
- {
|
|
|
- switch(hcan->State)
|
|
|
+
|
|
|
+ /* Check Tx Mailbox 1 status */
|
|
|
+ if ((hcan->Instance->TSR & CAN_TSR_TME1) != 0U)
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_BUSY_RX1 */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
- break;
|
|
|
+ freelevel++;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
+ /* Check Tx Mailbox 2 status */
|
|
|
+ if ((hcan->Instance->TSR & CAN_TSR_TME2) != 0U)
|
|
|
+ {
|
|
|
+ freelevel++;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- /* Return function status */
|
|
|
- return HAL_OK;
|
|
|
+ /* Return Tx Mailboxes free level */
|
|
|
+ return freelevel;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Receives a correct CAN frame.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
- * @param FIFONumber: Specify the FIFO number
|
|
|
- * @retval HAL status
|
|
|
+ * @brief Check if a transmission request is pending on the selected Tx
|
|
|
+ * Mailboxes.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @param TxMailboxes List of Tx Mailboxes to check.
|
|
|
+ * This parameter can be any combination of @arg CAN_Tx_Mailboxes.
|
|
|
+ * @retval Status
|
|
|
+ * - 0 : No pending transmission request on any selected Tx Mailboxes.
|
|
|
+ * - 1 : Pending transmission request on at least one of the selected
|
|
|
+ * Tx Mailbox.
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
|
|
|
+uint32_t HAL_CAN_IsTxMessagePending(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes)
|
|
|
{
|
|
|
- /* Check the parameters */
|
|
|
- assert_param(IS_CAN_FIFO(FIFONumber));
|
|
|
-
|
|
|
- /* Check if CAN state is not busy for RX FIFO0 */
|
|
|
- if((FIFONumber == CAN_FIFO0) && ((hcan->State == HAL_CAN_STATE_BUSY_RX0) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
|
|
|
+ uint32_t status = 0U;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ /* Check function parameters */
|
|
|
+ assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes));
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- return HAL_BUSY;
|
|
|
+ /* Check pending transmission request on the selected Tx Mailboxes */
|
|
|
+ if ((hcan->Instance->TSR & (TxMailboxes << CAN_TSR_TME0_Pos)) != (TxMailboxes << CAN_TSR_TME0_Pos))
|
|
|
+ {
|
|
|
+ status = 1U;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /* Check if CAN state is not busy for RX FIFO1 */
|
|
|
- if((FIFONumber == CAN_FIFO1) && ((hcan->State == HAL_CAN_STATE_BUSY_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_RX0_RX1) || \
|
|
|
- (hcan->State == HAL_CAN_STATE_BUSY_TX_RX0_RX1)))
|
|
|
+ /* Return status */
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Return timestamp of Tx message sent, if time triggered communication
|
|
|
+ mode is enabled.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @param TxMailbox Tx Mailbox where the timestamp of message sent will be
|
|
|
+ * read.
|
|
|
+ * This parameter can be one value of @arg CAN_Tx_Mailboxes.
|
|
|
+ * @retval Timestamp of message sent from Tx Mailbox.
|
|
|
+ */
|
|
|
+uint32_t HAL_CAN_GetTxTimestamp(CAN_HandleTypeDef *hcan, uint32_t TxMailbox)
|
|
|
+{
|
|
|
+ uint32_t timestamp = 0U;
|
|
|
+ uint32_t transmitmailbox;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ /* Check function parameters */
|
|
|
+ assert_param(IS_CAN_TX_MAILBOX(TxMailbox));
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- return HAL_BUSY;
|
|
|
+ /* Select the Tx mailbox */
|
|
|
+ transmitmailbox = POSITION_VAL(TxMailbox);
|
|
|
+
|
|
|
+ /* Get timestamp */
|
|
|
+ timestamp = (hcan->Instance->sTxMailBox[transmitmailbox].TDTR & CAN_TDT0R_TIME) >> CAN_TDT0R_TIME_Pos;
|
|
|
}
|
|
|
|
|
|
- /* Process locked */
|
|
|
- __HAL_LOCK(hcan);
|
|
|
+ /* Return the timestamp */
|
|
|
+ return timestamp;
|
|
|
+}
|
|
|
|
|
|
- /* Change CAN state */
|
|
|
- if(FIFONumber == CAN_FIFO0)
|
|
|
+/**
|
|
|
+ * @brief Get an CAN frame from the Rx FIFO zone into the message RAM.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @param RxFifo Fifo number of the received message to be read.
|
|
|
+ * This parameter can be a value of @arg CAN_receive_FIFO_number.
|
|
|
+ * @param pHeader pointer to a CAN_RxHeaderTypeDef structure where the header
|
|
|
+ * of the Rx frame will be stored.
|
|
|
+ * @param aData array where the payload of the Rx frame will be stored.
|
|
|
+ * @retval HAL status
|
|
|
+ */
|
|
|
+HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, CAN_RxHeaderTypeDef *pHeader, uint8_t aData[])
|
|
|
+{
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ assert_param(IS_CAN_RX_FIFO(RxFifo));
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- switch(hcan->State)
|
|
|
+ /* Check the Rx FIFO */
|
|
|
+ if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_TX):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_READY */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0;
|
|
|
- break;
|
|
|
+ /* Check that the Rx FIFO 0 is not empty */
|
|
|
+ if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) == 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
- {
|
|
|
- switch(hcan->State)
|
|
|
+ else /* Rx element is assigned to Rx FIFO 1 */
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_TX):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_READY */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX1;
|
|
|
- break;
|
|
|
+ /* Check that the Rx FIFO 1 is not empty */
|
|
|
+ if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) == 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_PARAM;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- /* Set CAN error code to none */
|
|
|
- hcan->ErrorCode = HAL_CAN_ERROR_NONE;
|
|
|
|
|
|
+ /* Get the header */
|
|
|
+ pHeader->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[RxFifo].RIR;
|
|
|
+ if (pHeader->IDE == CAN_ID_STD)
|
|
|
+ {
|
|
|
+ pHeader->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_TI0R_STID_Pos;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ pHeader->ExtId = ((CAN_RI0R_EXID | CAN_RI0R_STID) & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_EXID_Pos;
|
|
|
+ }
|
|
|
+ pHeader->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_RTR_Pos;
|
|
|
+ pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos;
|
|
|
+ pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos;
|
|
|
+ pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos;
|
|
|
+
|
|
|
+ /* Get the data */
|
|
|
+ aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos);
|
|
|
+ aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos);
|
|
|
+ aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos);
|
|
|
+ aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos);
|
|
|
+ aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos);
|
|
|
+ aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos);
|
|
|
+ aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos);
|
|
|
+ aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos);
|
|
|
+
|
|
|
+ /* Release the FIFO */
|
|
|
+ if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */
|
|
|
+ {
|
|
|
+ /* Release RX FIFO 0 */
|
|
|
+ SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0);
|
|
|
+ }
|
|
|
+ else /* Rx element is assigned to Rx FIFO 1 */
|
|
|
+ {
|
|
|
+ /* Release RX FIFO 1 */
|
|
|
+ SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1);
|
|
|
+ }
|
|
|
|
|
|
- /* Enable interrupts: */
|
|
|
- /* - Enable Error warning Interrupt */
|
|
|
- /* - Enable Error passive Interrupt */
|
|
|
- /* - Enable Bus-off Interrupt */
|
|
|
- /* - Enable Last error code Interrupt */
|
|
|
- /* - Enable Error Interrupt */
|
|
|
- /* - Enable Transmit mailbox empty Interrupt */
|
|
|
- __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
|
|
|
- CAN_IT_EPV |
|
|
|
- CAN_IT_BOF |
|
|
|
- CAN_IT_LEC |
|
|
|
- CAN_IT_ERR |
|
|
|
- CAN_IT_TME );
|
|
|
-
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
-
|
|
|
- if(FIFONumber == CAN_FIFO0)
|
|
|
- {
|
|
|
- /* Enable FIFO 0 overrun and message pending Interrupt */
|
|
|
- __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- /* Enable FIFO 1 overrun and message pending Interrupt */
|
|
|
- __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
+
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- /* Return function status */
|
|
|
- return HAL_OK;
|
|
|
+/**
|
|
|
+ * @brief Return Rx FIFO fill level.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @param RxFifo Rx FIFO.
|
|
|
+ * This parameter can be a value of @arg CAN_receive_FIFO_number.
|
|
|
+ * @retval Number of messages available in Rx FIFO.
|
|
|
+ */
|
|
|
+uint32_t HAL_CAN_GetRxFifoFillLevel(CAN_HandleTypeDef *hcan, uint32_t RxFifo)
|
|
|
+{
|
|
|
+ uint32_t filllevel = 0U;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ /* Check function parameters */
|
|
|
+ assert_param(IS_CAN_RX_FIFO(RxFifo));
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
+ {
|
|
|
+ if (RxFifo == CAN_RX_FIFO0)
|
|
|
+ {
|
|
|
+ filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0;
|
|
|
+ }
|
|
|
+ else /* RxFifo == CAN_RX_FIFO1 */
|
|
|
+ {
|
|
|
+ filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Return Rx FIFO fill level */
|
|
|
+ return filllevel;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Enters the Sleep (low power) mode.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @}
|
|
|
+ */
|
|
|
+
|
|
|
+/** @defgroup CAN_Exported_Functions_Group4 Interrupts management
|
|
|
+ * @brief Interrupts management
|
|
|
+ *
|
|
|
+@verbatim
|
|
|
+ ==============================================================================
|
|
|
+ ##### Interrupts management #####
|
|
|
+ ==============================================================================
|
|
|
+ [..] This section provides functions allowing to:
|
|
|
+ (+) HAL_CAN_ActivateNotification : Enable interrupts
|
|
|
+ (+) HAL_CAN_DeactivateNotification : Disable interrupts
|
|
|
+ (+) HAL_CAN_IRQHandler : Handles CAN interrupt request
|
|
|
+
|
|
|
+@endverbatim
|
|
|
+ * @{
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Enable interrupts.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
- * @retval HAL status.
|
|
|
+ * @param ActiveITs indicates which interrupts will be enabled.
|
|
|
+ * This parameter can be any combination of @arg CAN_Interrupts.
|
|
|
+ * @retval HAL status
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_Sleep(CAN_HandleTypeDef* hcan)
|
|
|
+HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs)
|
|
|
{
|
|
|
- uint32_t tickstart = 0U;
|
|
|
-
|
|
|
- /* Process locked */
|
|
|
- __HAL_LOCK(hcan);
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY;
|
|
|
-
|
|
|
- /* Request Sleep mode */
|
|
|
- MODIFY_REG(hcan->Instance->MCR,
|
|
|
- CAN_MCR_INRQ ,
|
|
|
- CAN_MCR_SLEEP );
|
|
|
-
|
|
|
- /* Sleep mode status */
|
|
|
- if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
|
|
|
- HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK) )
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ /* Check function parameters */
|
|
|
+ assert_param(IS_CAN_IT(ActiveITs));
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
+ /* Enable the selected interrupts */
|
|
|
+ __HAL_CAN_ENABLE_IT(hcan, ActiveITs);
|
|
|
|
|
|
/* Return function status */
|
|
|
- return HAL_ERROR;
|
|
|
+ return HAL_OK;
|
|
|
}
|
|
|
-
|
|
|
- /* Get tick */
|
|
|
- tickstart = HAL_GetTick();
|
|
|
-
|
|
|
- /* Wait the acknowledge */
|
|
|
- while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
|
|
|
- HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
|
|
|
+ else
|
|
|
{
|
|
|
- if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
- {
|
|
|
- hcan->State = HAL_CAN_STATE_TIMEOUT;
|
|
|
-
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
- return HAL_TIMEOUT;
|
|
|
- }
|
|
|
+ return HAL_ERROR;
|
|
|
}
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
-
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
-
|
|
|
- /* Return function status */
|
|
|
- return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Wakes up the CAN peripheral from sleep mode, after that the CAN peripheral
|
|
|
- * is in the normal mode.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @brief Disable interrupts.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
- * @retval HAL status.
|
|
|
+ * @param InactiveITs indicates which interrupts will be disabled.
|
|
|
+ * This parameter can be any combination of @arg CAN_Interrupts.
|
|
|
+ * @retval HAL status
|
|
|
*/
|
|
|
-HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef* hcan)
|
|
|
+HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs)
|
|
|
{
|
|
|
- uint32_t tickstart = 0U;
|
|
|
-
|
|
|
- /* Process locked */
|
|
|
- __HAL_LOCK(hcan);
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY;
|
|
|
-
|
|
|
- /* Wake up request */
|
|
|
- CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
|
|
|
-
|
|
|
- /* Get timeout */
|
|
|
- tickstart = HAL_GetTick();
|
|
|
-
|
|
|
- /* Sleep mode status */
|
|
|
- while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ /* Check function parameters */
|
|
|
+ assert_param(IS_CAN_IT(InactiveITs));
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
|
|
|
- {
|
|
|
- hcan->State= HAL_CAN_STATE_TIMEOUT;
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
- return HAL_TIMEOUT;
|
|
|
- }
|
|
|
+ /* Disable the selected interrupts */
|
|
|
+ __HAL_CAN_DISABLE_IT(hcan, InactiveITs);
|
|
|
+
|
|
|
+ /* Return function status */
|
|
|
+ return HAL_OK;
|
|
|
}
|
|
|
- if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
|
|
|
+ else
|
|
|
{
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
- /* Return function status */
|
|
|
return HAL_ERROR;
|
|
|
}
|
|
|
-
|
|
|
- /* Change CAN state */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
-
|
|
|
- /* Process unlocked */
|
|
|
- __HAL_UNLOCK(hcan);
|
|
|
-
|
|
|
- /* Return function status */
|
|
|
- return HAL_OK;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Handles CAN interrupt request
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @brief Handles CAN interrupt request
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
* @retval None
|
|
|
*/
|
|
|
-void HAL_CAN_IRQHandler(CAN_HandleTypeDef* hcan)
|
|
|
+void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
|
|
|
uint32_t errorcode = HAL_CAN_ERROR_NONE;
|
|
|
-
|
|
|
- /* Check Overrun flag for FIFO0 */
|
|
|
- tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0);
|
|
|
- if((tmp1 != 0U) && tmp2)
|
|
|
+ uint32_t interrupts = READ_REG(hcan->Instance->IER);
|
|
|
+ uint32_t msrflags = READ_REG(hcan->Instance->MSR);
|
|
|
+ uint32_t tsrflags = READ_REG(hcan->Instance->TSR);
|
|
|
+ uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R);
|
|
|
+ uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R);
|
|
|
+ uint32_t esrflags = READ_REG(hcan->Instance->ESR);
|
|
|
+
|
|
|
+ /* Transmit Mailbox empty interrupt management *****************************/
|
|
|
+ if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U)
|
|
|
{
|
|
|
- /* Set CAN error code to FOV0 error */
|
|
|
- errorcode |= HAL_CAN_ERROR_FOV0;
|
|
|
+ /* Transmit Mailbox 0 management *****************************************/
|
|
|
+ if ((tsrflags & CAN_TSR_RQCP0) != 0U)
|
|
|
+ {
|
|
|
+ /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0);
|
|
|
|
|
|
- /* Clear FIFO0 Overrun Flag */
|
|
|
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
|
|
|
- }
|
|
|
+ if ((tsrflags & CAN_TSR_TXOK0) != 0U)
|
|
|
+ {
|
|
|
+ /* Transmission Mailbox 0 complete callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_TxMailbox0CompleteCallback(hcan);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if ((tsrflags & CAN_TSR_ALST0) != 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ errorcode |= HAL_CAN_ERROR_TX_ALST0;
|
|
|
+ }
|
|
|
+ else if ((tsrflags & CAN_TSR_TERR0) != 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ errorcode |= HAL_CAN_ERROR_TX_TERR0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Transmission Mailbox 0 abort callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_TxMailbox0AbortCallback(hcan);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- /* Check Overrun flag for FIFO1 */
|
|
|
- tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1);
|
|
|
- if((tmp1 != 0U) && tmp2)
|
|
|
- {
|
|
|
- /* Set CAN error code to FOV1 error */
|
|
|
- errorcode |= HAL_CAN_ERROR_FOV1;
|
|
|
+ /* Transmit Mailbox 1 management *****************************************/
|
|
|
+ if ((tsrflags & CAN_TSR_RQCP1) != 0U)
|
|
|
+ {
|
|
|
+ /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1);
|
|
|
|
|
|
- /* Clear FIFO1 Overrun Flag */
|
|
|
- __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
|
|
|
- }
|
|
|
+ if ((tsrflags & CAN_TSR_TXOK1) != 0U)
|
|
|
+ {
|
|
|
+ /* Transmission Mailbox 1 complete callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_TxMailbox1CompleteCallback(hcan);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if ((tsrflags & CAN_TSR_ALST1) != 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ errorcode |= HAL_CAN_ERROR_TX_ALST1;
|
|
|
+ }
|
|
|
+ else if ((tsrflags & CAN_TSR_TERR1) != 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ errorcode |= HAL_CAN_ERROR_TX_TERR1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Transmission Mailbox 1 abort callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_TxMailbox1AbortCallback(hcan);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- /* Check End of transmission flag */
|
|
|
- if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
|
|
|
- {
|
|
|
- /* Check Transmit request completion status */
|
|
|
- tmp1 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0);
|
|
|
- tmp2 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1);
|
|
|
- tmp3 = __HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2);
|
|
|
- if(tmp1 || tmp2 || tmp3)
|
|
|
+ /* Transmit Mailbox 2 management *****************************************/
|
|
|
+ if ((tsrflags & CAN_TSR_RQCP2) != 0U)
|
|
|
{
|
|
|
- tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0);
|
|
|
- tmp2 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1);
|
|
|
- tmp3 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2);
|
|
|
- /* Check Transmit success */
|
|
|
- if((tmp1) || (tmp2) || (tmp3))
|
|
|
+ /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2);
|
|
|
+
|
|
|
+ if ((tsrflags & CAN_TSR_TXOK2) != 0U)
|
|
|
{
|
|
|
- /* Call transmit function */
|
|
|
- CAN_Transmit_IT(hcan);
|
|
|
+ /* Transmission Mailbox 2 complete callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_TxMailbox2CompleteCallback(hcan);
|
|
|
}
|
|
|
- else /* Transmit failure */
|
|
|
+ else
|
|
|
{
|
|
|
- /* Set CAN error code to TXFAIL error */
|
|
|
- errorcode |= HAL_CAN_ERROR_TXFAIL;
|
|
|
+ if ((tsrflags & CAN_TSR_ALST2) != 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ errorcode |= HAL_CAN_ERROR_TX_ALST2;
|
|
|
+ }
|
|
|
+ else if ((tsrflags & CAN_TSR_TERR2) != 0U)
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ errorcode |= HAL_CAN_ERROR_TX_TERR2;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Transmission Mailbox 2 abort callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_TxMailbox2AbortCallback(hcan);
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Receive FIFO 0 overrun interrupt management *****************************/
|
|
|
+ if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U)
|
|
|
+ {
|
|
|
+ if ((rf0rflags & CAN_RF0R_FOVR0) != 0U)
|
|
|
+ {
|
|
|
+ /* Set CAN error code to Rx Fifo 0 overrun error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_RX_FOV0;
|
|
|
|
|
|
- /* Clear transmission status flags (RQCPx and TXOKx) */
|
|
|
- SET_BIT(hcan->Instance->TSR, CAN_TSR_RQCP0 | CAN_TSR_RQCP1 | CAN_TSR_RQCP2 | \
|
|
|
- CAN_FLAG_TXOK0 | CAN_FLAG_TXOK1 | CAN_FLAG_TXOK2);
|
|
|
+ /* Clear FIFO0 Overrun Flag */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0);
|
|
|
- /* Check End of reception flag for FIFO0 */
|
|
|
- if((tmp1 != 0U) && tmp2)
|
|
|
+
|
|
|
+ /* Receive FIFO 0 full interrupt management ********************************/
|
|
|
+ if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U)
|
|
|
{
|
|
|
- /* Call receive function */
|
|
|
- CAN_Receive_IT(hcan, CAN_FIFO0);
|
|
|
+ if ((rf0rflags & CAN_RF0R_FULL0) != 0U)
|
|
|
+ {
|
|
|
+ /* Clear FIFO 0 full Flag */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0);
|
|
|
+
|
|
|
+ /* Receive FIFO 0 full Callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_RxFifo0FullCallback(hcan);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- tmp1 = __HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1);
|
|
|
- /* Check End of reception flag for FIFO1 */
|
|
|
- if((tmp1 != 0U) && tmp2)
|
|
|
+
|
|
|
+ /* Receive FIFO 0 message pending interrupt management *********************/
|
|
|
+ if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U)
|
|
|
{
|
|
|
- /* Call receive function */
|
|
|
- CAN_Receive_IT(hcan, CAN_FIFO1);
|
|
|
+ /* Check if message is still pending */
|
|
|
+ if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U)
|
|
|
+ {
|
|
|
+ /* Receive FIFO 0 mesage pending Callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_RxFifo0MsgPendingCallback(hcan);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /* Set error code in handle */
|
|
|
- hcan->ErrorCode |= errorcode;
|
|
|
+ /* Receive FIFO 1 overrun interrupt management *****************************/
|
|
|
+ if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U)
|
|
|
+ {
|
|
|
+ if ((rf1rflags & CAN_RF1R_FOVR1) != 0U)
|
|
|
+ {
|
|
|
+ /* Set CAN error code to Rx Fifo 1 overrun error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_RX_FOV1;
|
|
|
+
|
|
|
+ /* Clear FIFO1 Overrun Flag */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG);
|
|
|
- tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
|
|
|
- /* Check Error Warning Flag */
|
|
|
- if(tmp1 && tmp2 && tmp3)
|
|
|
+ /* Receive FIFO 1 full interrupt management ********************************/
|
|
|
+ if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U)
|
|
|
{
|
|
|
- /* Set CAN error code to EWG error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_EWG;
|
|
|
- /* No need for clear of Error Warning Flag as read-only */
|
|
|
+ if ((rf1rflags & CAN_RF1R_FULL1) != 0U)
|
|
|
+ {
|
|
|
+ /* Clear FIFO 1 full Flag */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1);
|
|
|
+
|
|
|
+ /* Receive FIFO 1 full Callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_RxFifo1FullCallback(hcan);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EPV);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EPV);
|
|
|
- tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
|
|
|
- /* Check Error Passive Flag */
|
|
|
- if(tmp1 && tmp2 && tmp3)
|
|
|
+
|
|
|
+ /* Receive FIFO 1 message pending interrupt management *********************/
|
|
|
+ if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U)
|
|
|
{
|
|
|
- /* Set CAN error code to EPV error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
|
|
|
- /* No need for clear of Error Passive Flag as read-only */
|
|
|
+ /* Check if message is still pending */
|
|
|
+ if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U)
|
|
|
+ {
|
|
|
+ /* Receive FIFO 1 mesage pending Callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_RxFifo1MsgPendingCallback(hcan);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- tmp1 = __HAL_CAN_GET_FLAG(hcan, CAN_FLAG_BOF);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_BOF);
|
|
|
- tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
|
|
|
- /* Check Bus-Off Flag */
|
|
|
- if(tmp1 && tmp2 && tmp3)
|
|
|
+
|
|
|
+ /* Sleep interrupt management *********************************************/
|
|
|
+ if ((interrupts & CAN_IT_SLEEP_ACK) != 0U)
|
|
|
{
|
|
|
- /* Set CAN error code to BOF error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_BOF;
|
|
|
- /* No need for clear of Bus-Off Flag as read-only */
|
|
|
+ if ((msrflags & CAN_MSR_SLAKI) != 0U)
|
|
|
+ {
|
|
|
+ /* Clear Sleep interrupt Flag */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI);
|
|
|
+
|
|
|
+ /* Sleep Callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_SleepCallback(hcan);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- tmp1 = HAL_IS_BIT_CLR(hcan->Instance->ESR, CAN_ESR_LEC);
|
|
|
- tmp2 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_LEC);
|
|
|
- tmp3 = __HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_ERR);
|
|
|
- /* Check Last error code Flag */
|
|
|
- if((!tmp1) && tmp2 && tmp3)
|
|
|
+
|
|
|
+ /* WakeUp interrupt management *********************************************/
|
|
|
+ if ((interrupts & CAN_IT_WAKEUP) != 0U)
|
|
|
{
|
|
|
- tmp1 = (hcan->Instance->ESR & CAN_ESR_LEC);
|
|
|
- switch(tmp1)
|
|
|
+ if ((msrflags & CAN_MSR_WKUI) != 0U)
|
|
|
{
|
|
|
- case(CAN_ESR_LEC_0):
|
|
|
- /* Set CAN error code to STF error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_STF;
|
|
|
- break;
|
|
|
- case(CAN_ESR_LEC_1):
|
|
|
- /* Set CAN error code to FOR error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_FOR;
|
|
|
- break;
|
|
|
- case(CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
|
|
|
- /* Set CAN error code to ACK error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_ACK;
|
|
|
- break;
|
|
|
- case(CAN_ESR_LEC_2):
|
|
|
- /* Set CAN error code to BR error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_BR;
|
|
|
- break;
|
|
|
- case(CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
|
|
|
- /* Set CAN error code to BD error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_BD;
|
|
|
- break;
|
|
|
- case(CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
|
|
|
- /* Set CAN error code to CRC error */
|
|
|
- hcan->ErrorCode |= HAL_CAN_ERROR_CRC;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
+ /* Clear WakeUp Flag */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU);
|
|
|
+
|
|
|
+ /* WakeUp Callback */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
+ HAL_CAN_WakeUpFromRxMsgCallback(hcan);
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Error interrupts management *********************************************/
|
|
|
+ if ((interrupts & CAN_IT_ERROR) != 0U)
|
|
|
+ {
|
|
|
+ if ((msrflags & CAN_MSR_ERRI) != 0U)
|
|
|
+ {
|
|
|
+ /* Check Error Warning Flag */
|
|
|
+ if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) &&
|
|
|
+ ((esrflags & CAN_ESR_EWGF) != 0U))
|
|
|
+ {
|
|
|
+ /* Set CAN error code to Error Warning */
|
|
|
+ errorcode |= HAL_CAN_ERROR_EWG;
|
|
|
+
|
|
|
+ /* No need for clear of Error Warning Flag as read-only */
|
|
|
+ }
|
|
|
|
|
|
- /* Clear Last error code Flag */
|
|
|
- CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
|
|
|
+ /* Check Error Passive Flag */
|
|
|
+ if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) &&
|
|
|
+ ((esrflags & CAN_ESR_EPVF) != 0U))
|
|
|
+ {
|
|
|
+ /* Set CAN error code to Error Passive */
|
|
|
+ errorcode |= HAL_CAN_ERROR_EPV;
|
|
|
+
|
|
|
+ /* No need for clear of Error Passive Flag as read-only */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check Bus-off Flag */
|
|
|
+ if (((interrupts & CAN_IT_BUSOFF) != 0U) &&
|
|
|
+ ((esrflags & CAN_ESR_BOFF) != 0U))
|
|
|
+ {
|
|
|
+ /* Set CAN error code to Bus-Off */
|
|
|
+ errorcode |= HAL_CAN_ERROR_BOF;
|
|
|
+
|
|
|
+ /* No need for clear of Error Bus-Off as read-only */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Check Last Error Code Flag */
|
|
|
+ if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) &&
|
|
|
+ ((esrflags & CAN_ESR_LEC) != 0U))
|
|
|
+ {
|
|
|
+ switch (esrflags & CAN_ESR_LEC)
|
|
|
+ {
|
|
|
+ case (CAN_ESR_LEC_0):
|
|
|
+ /* Set CAN error code to Stuff error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_STF;
|
|
|
+ break;
|
|
|
+ case (CAN_ESR_LEC_1):
|
|
|
+ /* Set CAN error code to Form error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_FOR;
|
|
|
+ break;
|
|
|
+ case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0):
|
|
|
+ /* Set CAN error code to Acknowledgement error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_ACK;
|
|
|
+ break;
|
|
|
+ case (CAN_ESR_LEC_2):
|
|
|
+ /* Set CAN error code to Bit recessive error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_BR;
|
|
|
+ break;
|
|
|
+ case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0):
|
|
|
+ /* Set CAN error code to Bit Dominant error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_BD;
|
|
|
+ break;
|
|
|
+ case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1):
|
|
|
+ /* Set CAN error code to CRC error */
|
|
|
+ errorcode |= HAL_CAN_ERROR_CRC;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Clear Last error code Flag */
|
|
|
+ CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Clear ERRI Flag */
|
|
|
+ __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI);
|
|
|
}
|
|
|
|
|
|
/* Call the Error call Back in case of Errors */
|
|
|
- if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
|
|
|
+ if (errorcode != HAL_CAN_ERROR_NONE)
|
|
|
{
|
|
|
- /* Clear ERRI Flag */
|
|
|
- hcan->Instance->MSR = CAN_MSR_ERRI;
|
|
|
- /* Set the CAN state ready to be able to start again the process */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
-
|
|
|
- /* Disable interrupts: */
|
|
|
- /* - Disable Error warning Interrupt */
|
|
|
- /* - Disable Error passive Interrupt */
|
|
|
- /* - Disable Bus-off Interrupt */
|
|
|
- /* - Disable Last error code Interrupt */
|
|
|
- /* - Disable Error Interrupt */
|
|
|
- /* - Disable FIFO 0 message pending Interrupt */
|
|
|
- /* - Disable FIFO 0 Overrun Interrupt */
|
|
|
- /* - Disable FIFO 1 message pending Interrupt */
|
|
|
- /* - Disable FIFO 1 Overrun Interrupt */
|
|
|
- /* - Disable Transmit mailbox empty Interrupt */
|
|
|
- __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
|
|
|
- CAN_IT_EPV |
|
|
|
- CAN_IT_BOF |
|
|
|
- CAN_IT_LEC |
|
|
|
- CAN_IT_ERR |
|
|
|
- CAN_IT_FMP0|
|
|
|
- CAN_IT_FOV0|
|
|
|
- CAN_IT_FMP1|
|
|
|
- CAN_IT_FOV1|
|
|
|
- CAN_IT_TME );
|
|
|
+ /* Update error code in handle */
|
|
|
+ hcan->ErrorCode |= errorcode;
|
|
|
|
|
|
/* Call Error callback function */
|
|
|
+ /* Call weak (surcharged) callback */
|
|
|
HAL_CAN_ErrorCallback(hcan);
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Transmission complete callback in non blocking mode
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @}
|
|
|
+ */
|
|
|
+
|
|
|
+/** @defgroup CAN_Exported_Functions_Group5 Callback functions
|
|
|
+ * @brief CAN Callback functions
|
|
|
+ *
|
|
|
+@verbatim
|
|
|
+ ==============================================================================
|
|
|
+ ##### Callback functions #####
|
|
|
+ ==============================================================================
|
|
|
+ [..]
|
|
|
+ This subsection provides the following callback functions:
|
|
|
+ (+) HAL_CAN_TxMailbox0CompleteCallback
|
|
|
+ (+) HAL_CAN_TxMailbox1CompleteCallback
|
|
|
+ (+) HAL_CAN_TxMailbox2CompleteCallback
|
|
|
+ (+) HAL_CAN_TxMailbox0AbortCallback
|
|
|
+ (+) HAL_CAN_TxMailbox1AbortCallback
|
|
|
+ (+) HAL_CAN_TxMailbox2AbortCallback
|
|
|
+ (+) HAL_CAN_RxFifo0MsgPendingCallback
|
|
|
+ (+) HAL_CAN_RxFifo0FullCallback
|
|
|
+ (+) HAL_CAN_RxFifo1MsgPendingCallback
|
|
|
+ (+) HAL_CAN_RxFifo1FullCallback
|
|
|
+ (+) HAL_CAN_SleepCallback
|
|
|
+ (+) HAL_CAN_WakeUpFromRxMsgCallback
|
|
|
+ (+) HAL_CAN_ErrorCallback
|
|
|
+
|
|
|
+@endverbatim
|
|
|
+ * @{
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Transmission Mailbox 0 complete callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
* @retval None
|
|
|
*/
|
|
|
-__weak void HAL_CAN_TxCpltCallback(CAN_HandleTypeDef* hcan)
|
|
|
+__weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
UNUSED(hcan);
|
|
|
+
|
|
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
- the HAL_CAN_TxCpltCallback can be implemented in the user file
|
|
|
+ the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the
|
|
|
+ user file
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Transmission complete callback in non blocking mode
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @brief Transmission Mailbox 1 complete callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
* @retval None
|
|
|
*/
|
|
|
-__weak void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
|
|
|
+__weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
UNUSED(hcan);
|
|
|
+
|
|
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
- the HAL_CAN_RxCpltCallback can be implemented in the user file
|
|
|
+ the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the
|
|
|
+ user file
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Error CAN callback.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @brief Transmission Mailbox 2 complete callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
* @retval None
|
|
|
*/
|
|
|
-__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
|
|
|
+__weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
UNUSED(hcan);
|
|
|
+
|
|
|
/* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
- the HAL_CAN_ErrorCallback can be implemented in the user file
|
|
|
+ the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the
|
|
|
+ user file
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @}
|
|
|
+ * @brief Transmission Mailbox 0 Cancellation callback.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
+__weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
|
|
|
-/** @defgroup CAN_Exported_Functions_Group3 Peripheral State and Error functions
|
|
|
- * @brief CAN Peripheral State functions
|
|
|
- *
|
|
|
-@verbatim
|
|
|
- ==============================================================================
|
|
|
- ##### Peripheral State and Error functions #####
|
|
|
- ==============================================================================
|
|
|
- [..]
|
|
|
- This subsection provides functions allowing to :
|
|
|
- (+) Check the CAN state.
|
|
|
- (+) Check CAN Errors detected during interrupt process
|
|
|
-
|
|
|
-@endverbatim
|
|
|
- * @{
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_TxMailbox0AbortCallback could be implemented in the
|
|
|
+ user file
|
|
|
+ */
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Transmission Mailbox 1 Cancellation callback.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
+__weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
+
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_TxMailbox1AbortCallback could be implemented in the
|
|
|
+ user file
|
|
|
+ */
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * @brief return the CAN state
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @brief Transmission Mailbox 2 Cancellation callback.
|
|
|
+ * @param hcan pointer to an CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
- * @retval HAL state
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
-HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef* hcan)
|
|
|
+__weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- /* Return CAN state */
|
|
|
- return hcan->State;
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
+
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_TxMailbox2AbortCallback could be implemented in the
|
|
|
+ user file
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Return the CAN error code
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * @brief Rx FIFO 0 message pending callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
* the configuration information for the specified CAN.
|
|
|
- * @retval CAN Error Code
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
-uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
|
|
|
+__weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- return hcan->ErrorCode;
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
+
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the
|
|
|
+ user file
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @}
|
|
|
+ * @brief Rx FIFO 0 full callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
+__weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
+
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_RxFifo0FullCallback could be implemented in the user
|
|
|
+ file
|
|
|
+ */
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * @}
|
|
|
+ * @brief Rx FIFO 1 message pending callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
+__weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
|
|
|
-/** @addtogroup CAN_Private_Functions
|
|
|
- * @{
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
|
|
|
+ user file
|
|
|
+ */
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Rx FIFO 1 full callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
+__weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
+
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_RxFifo1FullCallback could be implemented in the user
|
|
|
+ file
|
|
|
+ */
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
- * @brief Initiates and transmits a CAN frame message.
|
|
|
- * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
- * @retval HAL status
|
|
|
+ * @brief Sleep callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval None
|
|
|
*/
|
|
|
-static HAL_StatusTypeDef CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
|
|
|
+__weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- /* Disable Transmit mailbox empty Interrupt */
|
|
|
- __HAL_CAN_DISABLE_IT(hcan, CAN_IT_TME);
|
|
|
-
|
|
|
- if(hcan->State == HAL_CAN_STATE_BUSY_TX)
|
|
|
- {
|
|
|
- /* Disable interrupts: */
|
|
|
- /* - Disable Error warning Interrupt */
|
|
|
- /* - Disable Error passive Interrupt */
|
|
|
- /* - Disable Bus-off Interrupt */
|
|
|
- /* - Disable Last error code Interrupt */
|
|
|
- /* - Disable Error Interrupt */
|
|
|
- __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
|
|
|
- CAN_IT_EPV |
|
|
|
- CAN_IT_BOF |
|
|
|
- CAN_IT_LEC |
|
|
|
- CAN_IT_ERR);
|
|
|
- }
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
|
|
|
- /* Change CAN state */
|
|
|
- switch(hcan->State)
|
|
|
- {
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_BUSY_TX */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
- break;
|
|
|
- }
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_SleepCallback could be implemented in the user file
|
|
|
+ */
|
|
|
+}
|
|
|
|
|
|
- /* Transmission complete callback */
|
|
|
- HAL_CAN_TxCpltCallback(hcan);
|
|
|
-
|
|
|
- return HAL_OK;
|
|
|
+/**
|
|
|
+ * @brief WakeUp from Rx message callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+__weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
+
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the
|
|
|
+ user file
|
|
|
+ */
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Receives a correct CAN frame.
|
|
|
- * @param hcan: Pointer to a CAN_HandleTypeDef structure that contains
|
|
|
- * the configuration information for the specified CAN.
|
|
|
- * @param FIFONumber: Specify the FIFO number
|
|
|
- * @retval HAL status
|
|
|
+ * @brief Error CAN callback.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
* @retval None
|
|
|
*/
|
|
|
-static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
|
|
|
+__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan)
|
|
|
{
|
|
|
- uint32_t tmp1 = 0U;
|
|
|
- CanRxMsgTypeDef* pRxMsg = NULL;
|
|
|
+ /* Prevent unused argument(s) compilation warning */
|
|
|
+ UNUSED(hcan);
|
|
|
|
|
|
- /* Set RxMsg pointer */
|
|
|
- if(FIFONumber == CAN_FIFO0)
|
|
|
- {
|
|
|
- pRxMsg = hcan->pRxMsg;
|
|
|
- }
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
- {
|
|
|
- pRxMsg = hcan->pRx1Msg;
|
|
|
- }
|
|
|
+ /* NOTE : This function Should not be modified, when the callback is needed,
|
|
|
+ the HAL_CAN_ErrorCallback could be implemented in the user file
|
|
|
+ */
|
|
|
+}
|
|
|
|
|
|
- /* Get the Id */
|
|
|
- pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
|
|
|
- if (pRxMsg->IDE == CAN_ID_STD)
|
|
|
- {
|
|
|
- pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
|
|
|
- }
|
|
|
-
|
|
|
- pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
|
|
|
- /* Get the DLC */
|
|
|
- pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
|
|
|
- /* Get the FIFONumber */
|
|
|
- pRxMsg->FIFONumber = FIFONumber;
|
|
|
- /* Get the FMI */
|
|
|
- pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
|
|
|
- /* Get the data field */
|
|
|
- pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
|
|
|
- pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
|
|
|
- pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
|
|
|
- pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
|
|
|
- pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
|
|
|
- pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
|
|
|
- pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
|
|
|
- pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
|
|
|
- /* Release the FIFO */
|
|
|
- /* Release FIFO0 */
|
|
|
- if (FIFONumber == CAN_FIFO0)
|
|
|
- {
|
|
|
- __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
|
|
|
-
|
|
|
- /* Disable FIFO 0 overrun and message pending Interrupt */
|
|
|
- __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV0 | CAN_IT_FMP0);
|
|
|
- }
|
|
|
- /* Release FIFO1 */
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
- {
|
|
|
- __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
|
|
|
-
|
|
|
- /* Disable FIFO 1 overrun and message pending Interrupt */
|
|
|
- __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
|
|
|
- }
|
|
|
+/**
|
|
|
+ * @}
|
|
|
+ */
|
|
|
|
|
|
- tmp1 = hcan->State;
|
|
|
- if((tmp1 == HAL_CAN_STATE_BUSY_RX0) || (tmp1 == HAL_CAN_STATE_BUSY_RX1))
|
|
|
- {
|
|
|
- /* Disable interrupts: */
|
|
|
- /* - Disable Error warning Interrupt */
|
|
|
- /* - Disable Error passive Interrupt */
|
|
|
- /* - Disable Bus-off Interrupt */
|
|
|
- /* - Disable Last error code Interrupt */
|
|
|
- /* - Disable Error Interrupt */
|
|
|
- __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG |
|
|
|
- CAN_IT_EPV |
|
|
|
- CAN_IT_BOF |
|
|
|
- CAN_IT_LEC |
|
|
|
- CAN_IT_ERR);
|
|
|
- }
|
|
|
+/** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions
|
|
|
+ * @brief CAN Peripheral State functions
|
|
|
+ *
|
|
|
+@verbatim
|
|
|
+ ==============================================================================
|
|
|
+ ##### Peripheral State and Error functions #####
|
|
|
+ ==============================================================================
|
|
|
+ [..]
|
|
|
+ This subsection provides functions allowing to :
|
|
|
+ (+) HAL_CAN_GetState() : Return the CAN state.
|
|
|
+ (+) HAL_CAN_GetError() : Return the CAN error codes if any.
|
|
|
+ (+) HAL_CAN_ResetError(): Reset the CAN error codes if any.
|
|
|
|
|
|
- /* Change CAN state */
|
|
|
- if (FIFONumber == CAN_FIFO0)
|
|
|
+@endverbatim
|
|
|
+ * @{
|
|
|
+ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Return the CAN state.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval HAL state
|
|
|
+ */
|
|
|
+HAL_CAN_StateTypeDef HAL_CAN_GetState(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
{
|
|
|
- switch(hcan->State)
|
|
|
+ /* Check sleep mode acknowledge flag */
|
|
|
+ if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U)
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX1;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX1;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_BUSY_RX0 */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
- break;
|
|
|
+ /* Sleep mode is active */
|
|
|
+ state = HAL_CAN_STATE_SLEEP_ACTIVE;
|
|
|
}
|
|
|
- }
|
|
|
- else /* FIFONumber == CAN_FIFO1 */
|
|
|
- {
|
|
|
- switch(hcan->State)
|
|
|
+ /* Check sleep mode request flag */
|
|
|
+ else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U)
|
|
|
{
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_RX0;
|
|
|
- break;
|
|
|
- case(HAL_CAN_STATE_BUSY_TX_RX0_RX1):
|
|
|
- hcan->State = HAL_CAN_STATE_BUSY_TX_RX0;
|
|
|
- break;
|
|
|
- default: /* HAL_CAN_STATE_BUSY_RX1 */
|
|
|
- hcan->State = HAL_CAN_STATE_READY;
|
|
|
- break;
|
|
|
+ /* Sleep mode request is pending */
|
|
|
+ state = HAL_CAN_STATE_SLEEP_PENDING;
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Neither sleep mode request nor sleep mode acknowledge */
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Return CAN state */
|
|
|
+ return state;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Return the CAN error code.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval CAN Error Code
|
|
|
+ */
|
|
|
+uint32_t HAL_CAN_GetError(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ /* Return CAN error code */
|
|
|
+ return hcan->ErrorCode;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Reset the CAN error code.
|
|
|
+ * @param hcan pointer to a CAN_HandleTypeDef structure that contains
|
|
|
+ * the configuration information for the specified CAN.
|
|
|
+ * @retval HAL status
|
|
|
+ */
|
|
|
+HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan)
|
|
|
+{
|
|
|
+ HAL_StatusTypeDef status = HAL_OK;
|
|
|
+ HAL_CAN_StateTypeDef state = hcan->State;
|
|
|
+
|
|
|
+ if ((state == HAL_CAN_STATE_READY) ||
|
|
|
+ (state == HAL_CAN_STATE_LISTENING))
|
|
|
+ {
|
|
|
+ /* Reset CAN error code */
|
|
|
+ hcan->ErrorCode = 0U;
|
|
|
}
|
|
|
+ else
|
|
|
+ {
|
|
|
+ /* Update error code */
|
|
|
+ hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED;
|
|
|
|
|
|
- /* Receive complete callback */
|
|
|
- HAL_CAN_RxCpltCallback(hcan);
|
|
|
+ status = HAL_ERROR;
|
|
|
+ }
|
|
|
|
|
|
- /* Return function status */
|
|
|
- return HAL_OK;
|
|
|
+ /* Return the status */
|
|
|
+ return status;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @}
|
|
|
*/
|
|
|
-#endif /* STM32F103x6) || STM32F103xB || STM32F103xE || STM32F103xG) || STM32F105xC || STM32F107xC */
|
|
|
+
|
|
|
+/**
|
|
|
+ * @}
|
|
|
+ */
|
|
|
|
|
|
#endif /* HAL_CAN_MODULE_ENABLED */
|
|
|
+
|
|
|
/**
|
|
|
* @}
|
|
|
*/
|
|
|
|
|
|
+#endif /* CAN1 */
|
|
|
+
|
|
|
/**
|
|
|
* @}
|
|
|
*/
|