mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Revision:
180:96ed750bd169
Parent:
156:95d6b41a828b
--- a/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_can.c	Thu Dec 07 14:01:42 2017 +0000
+++ b/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_can.c	Wed Jan 17 15:23:54 2018 +0000
@@ -2,8 +2,6 @@
   ******************************************************************************
   * @file    stm32f0xx_hal_can.c
   * @author  MCD Application Team
-  * @version V1.5.0
-  * @date    04-November-2016
   * @brief   CAN HAL module driver.
   *          This file provides firmware functions to manage the following 
   *          functionalities of the Controller Area Network (CAN) peripheral:
@@ -28,9 +26,13 @@
       (#) Initialise 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 ***
      =================================
      [..]    
@@ -157,10 +159,10 @@
   */
   
 /**
-  * @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.  
+  * @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.  
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan)
@@ -200,18 +202,18 @@
   hcan->State = HAL_CAN_STATE_BUSY;
   
   /* Exit from sleep mode */
-  hcan->Instance->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
+  CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
 
   /* Request initialisation */
-  hcan->Instance->MCR |= CAN_MCR_INRQ ;
+  SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
 
   /* Get tick */
   tickstart = HAL_GetTick();   
   
   /* Wait the acknowledge */
-  while((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
+  while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
   {
-    if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
+    if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
     {
       hcan->State= HAL_CAN_STATE_TIMEOUT;
       /* Process unlocked */
@@ -221,95 +223,97 @@
   }
 
   /* Check acknowledge */
-  if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
+  if (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
   {
     /* Set the time triggered communication mode */
     if (hcan->Init.TTCM == ENABLE)
     {
-      hcan->Instance->MCR |= CAN_MCR_TTCM;
+      SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
     }
     else
     {
-      hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TTCM;
+      CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM);
     }
 
     /* Set the automatic bus-off management */
     if (hcan->Init.ABOM == ENABLE)
     {
-      hcan->Instance->MCR |= CAN_MCR_ABOM;
+      SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
     }
     else
     {
-      hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_ABOM;
+      CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM);
     }
 
     /* Set the automatic wake-up mode */
     if (hcan->Init.AWUM == ENABLE)
     {
-      hcan->Instance->MCR |= CAN_MCR_AWUM;
+      SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
     }
     else
     {
-      hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_AWUM;
+      CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM);
     }
 
     /* Set the no automatic retransmission */
     if (hcan->Init.NART == ENABLE)
     {
-      hcan->Instance->MCR |= CAN_MCR_NART;
+      SET_BIT(hcan->Instance->MCR, CAN_MCR_NART);
     }
     else
     {
-      hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_NART;
+      CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART);
     }
 
     /* Set the receive FIFO locked mode */
     if (hcan->Init.RFLM == ENABLE)
     {
-      hcan->Instance->MCR |= CAN_MCR_RFLM;
+      SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
     }
     else
     {
-      hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_RFLM;
+      CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM);
     }
 
     /* Set the transmit FIFO priority */
     if (hcan->Init.TXFP == ENABLE)
     {
-      hcan->Instance->MCR |= CAN_MCR_TXFP;
+      SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
     }
     else
     {
-      hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_TXFP;
+      CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP);
     }
 
     /* Set the bit timing register */
-    hcan->Instance->BTR = (uint32_t)((uint32_t)hcan->Init.Mode) | \
-                ((uint32_t)hcan->Init.SJW) | \
-                ((uint32_t)hcan->Init.BS1) | \
-                ((uint32_t)hcan->Init.BS2) | \
-               ((uint32_t)hcan->Init.Prescaler - 1U);
+    WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode           |
+                                              hcan->Init.SJW            |
+                                              hcan->Init.BS1            |
+                                              hcan->Init.BS2            |
+                                              (hcan->Init.Prescaler - 1U) ));
 
     /* Request leave initialisation */
-    hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_INRQ;
+    CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ);
 
     /* Get tick */
     tickstart = HAL_GetTick();   
    
     /* Wait the acknowledge */
-    while((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
+    while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK))
     {
-      if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
+      if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE)
       {
-       hcan->State= HAL_CAN_STATE_TIMEOUT;
+         hcan->State= HAL_CAN_STATE_TIMEOUT;
+
        /* Process unlocked */
        __HAL_UNLOCK(hcan);
-        return HAL_TIMEOUT;
+
+       return HAL_TIMEOUT;
       }
     }
 
     /* Check acknowledged */
-    if ((hcan->Instance->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
+    if(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK))
     {
       status = CAN_INITSTATUS_SUCCESS;
     }
@@ -339,15 +343,15 @@
 /**
   * @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
+  * @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
+  * @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 = 0;
+  uint32_t filternbrbitpos = 0U;
   
   /* Check the parameters */
   assert_param(IS_CAN_FILTER_NUMBER(sFilterConfig->FilterNumber));
@@ -360,81 +364,80 @@
   filternbrbitpos = (1U) << sFilterConfig->FilterNumber;
 
   /* Initialisation mode for the filter */
-  hcan->Instance->FMR |= (uint32_t)CAN_FMR_FINIT;
-
   /* Select the start slave bank */
-  hcan->Instance->FMR &= ~((uint32_t)CAN_FMR_CAN2SB);
-  hcan->Instance->FMR |= (uint32_t)(sFilterConfig->BankNumber << 8U);
-  
-  /* Filter Deactivation */
-  hcan->Instance->FA1R &= ~(uint32_t)filternbrbitpos;
+  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)
   {
     /* 16-bit scale for the filter */
-    hcan->Instance->FS1R &= ~(uint32_t)filternbrbitpos;
+    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 = 
-       ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) |
-        (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
+       ((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 = 
-       ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
-        (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh);
+       ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
+        (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh);
   }
 
   if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT)
   {
     /* 32-bit scale for the filter */
-    hcan->Instance->FS1R |= filternbrbitpos;
+    SET_BIT(hcan->Instance->FS1R, filternbrbitpos);
+
     /* 32-bit identifier or First 32-bit identifier */
     hcan->Instance->sFilterRegister[sFilterConfig->FilterNumber].FR1 = 
-       ((0x0000FFFF & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) |
-        (0x0000FFFF & (uint32_t)sFilterConfig->FilterIdLow);
+       ((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 = 
-       ((0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
-        (0x0000FFFF & (uint32_t)sFilterConfig->FilterMaskIdLow);
+       ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) |
+        (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow);
   }
 
   /* Filter Mode */
   if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK)
   {
     /*Id/Mask mode for the filter*/
-    hcan->Instance->FM1R &= ~(uint32_t)filternbrbitpos;
+    CLEAR_BIT(hcan->Instance->FM1R, filternbrbitpos);
   }
   else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
   {
     /*Identifier list mode for the filter*/
-    hcan->Instance->FM1R |= (uint32_t)filternbrbitpos;
+    SET_BIT(hcan->Instance->FM1R, filternbrbitpos);
   }
 
   /* Filter FIFO assignment */
   if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0)
   {
     /* FIFO 0 assignation for the filter */
-    hcan->Instance->FFA1R &= ~(uint32_t)filternbrbitpos;
+    CLEAR_BIT(hcan->Instance->FFA1R, filternbrbitpos);
   }
-
-  if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO1)
+  else
   {
     /* FIFO 1 assignation for the filter */
-    hcan->Instance->FFA1R |= (uint32_t)filternbrbitpos;
+    SET_BIT(hcan->Instance->FFA1R, filternbrbitpos);
   }
   
   /* Filter activation */
   if (sFilterConfig->FilterActivation == ENABLE)
   {
-    hcan->Instance->FA1R |= filternbrbitpos;
+    SET_BIT(hcan->Instance->FA1R, filternbrbitpos);
   }
 
   /* Leave the initialisation mode for the filter */
-  hcan->Instance->FMR &= ~((uint32_t)CAN_FMR_FINIT);
+  CLEAR_BIT(hcan->Instance->FMR, ((uint32_t)CAN_FMR_FINIT));
   
   /* Return function status */
   return HAL_OK;
@@ -442,7 +445,7 @@
 
 /**
   * @brief  Deinitializes the CANx peripheral registers to their default reset values. 
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
   * @retval HAL status
   */
@@ -475,7 +478,7 @@
 
 /**
   * @brief  Initializes the CAN MSP.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
   * @retval None
   */
@@ -491,7 +494,7 @@
 
 /**
   * @brief  DeInitializes the CAN MSP.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
   * @retval None
   */
@@ -528,9 +531,9 @@
 
 /**
   * @brief  Initiates and transmits a CAN frame message.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
-  * @param  Timeout: Timeout duration.
+  * @param  Timeout Timeout duration.
   * @retval HAL status
   */
 HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
@@ -542,37 +545,43 @@
   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))
-  {  
+  {
     /* Process locked */
     __HAL_LOCK(hcan);
-    
-    if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
+
+    /* Change CAN state */
+    switch(hcan->State)
     {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
+      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;
+    }
+
+    /* 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
     {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_BUSY_TX;
-    }
-    
-    /* Select one empty transmit mailbox */
-    if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
-    {
-      transmitmailbox = 0U;
-    }
-    else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
-    {
-      transmitmailbox = 1U;
-    }
-      else
-    {
-      transmitmailbox = 2U;
+      transmitmailbox = CAN_TXMAILBOX_2;
     }
 
     /* Set up the Id */
@@ -580,15 +589,15 @@
     if (hcan->pTxMsg->IDE == CAN_ID_STD)
     {
       assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId));  
-      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21U) | \
-                                                  hcan->pTxMsg->RTR);
+      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 << 3U) | \
-                                                  hcan->pTxMsg->IDE | \
-                                                  hcan->pTxMsg->RTR);
+      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
+                                                           hcan->pTxMsg->IDE | \
+                                                           hcan->pTxMsg->RTR);
     }
     
     /* Set up the DLC */
@@ -597,16 +606,17 @@
     hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC;
 
     /* Set up the data field */
-    hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24U) | 
-                                             ((uint32_t)hcan->pTxMsg->Data[2] << 16U) |
-                                             ((uint32_t)hcan->pTxMsg->Data[1] << 8U) | 
-                                             ((uint32_t)hcan->pTxMsg->Data[0]));
-    hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24U) | 
-                                             ((uint32_t)hcan->pTxMsg->Data[6] << 16U) |
-                                             ((uint32_t)hcan->pTxMsg->Data[5] << 8U) |
-                                             ((uint32_t)hcan->pTxMsg->Data[4]));
+    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 */
-    hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
+    SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ);
   
     /* Get tick */
     tickstart = HAL_GetTick();   
@@ -617,26 +627,37 @@
       /* Check for the Timeout */
       if(Timeout != HAL_MAX_DELAY)
       {
-        if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+        if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
         {
           hcan->State = HAL_CAN_STATE_TIMEOUT;
+
+          /* Cancel transmission */
+          __HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
+
           /* Process unlocked */
           __HAL_UNLOCK(hcan);
           return HAL_TIMEOUT;
         }
       }
     }
-    if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
+
+    /* Change CAN state */
+    switch(hcan->State)
     {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_BUSY_RX;
+      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;
     }
-    else
-    {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_READY;
-    }
-    
+
     /* Process unlocked */
     __HAL_UNLOCK(hcan);
     
@@ -647,7 +668,7 @@
   {
     /* Change CAN state */
     hcan->State = HAL_CAN_STATE_ERROR; 
-    
+
     /* Return function status */
     return HAL_ERROR;
   }
@@ -655,7 +676,7 @@
 
 /**
   * @brief  Initiates and transmits a CAN frame message.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
   * @retval HAL status
   */
@@ -667,7 +688,7 @@
   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))
@@ -676,92 +697,94 @@
     __HAL_LOCK(hcan);
     
     /* Select one empty transmit mailbox */
-    if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
+    if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0))
     {
-      transmitmailbox = 0U;
+      transmitmailbox = CAN_TXMAILBOX_0;
     }
-    else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
+    else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1))
     {
-      transmitmailbox = 1U;
+      transmitmailbox = CAN_TXMAILBOX_1;
     }
     else
     {
-      transmitmailbox = 2U;
+      transmitmailbox = CAN_TXMAILBOX_2;
     }
 
     /* 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 << 21U) | \
-                                                hcan->pTxMsg->RTR);
+      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 << 3U) | \
-                                                hcan->pTxMsg->IDE | \
-                                                hcan->pTxMsg->RTR);
+      hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_Pos) | \
+                                                           hcan->pTxMsg->IDE |                         \
+                                                           hcan->pTxMsg->RTR);
     }
-  
+
     /* 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 */
-    hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24U) | 
-                                           ((uint32_t)hcan->pTxMsg->Data[2] << 16U) |
-                                           ((uint32_t)hcan->pTxMsg->Data[1] << 8U) | 
-                                           ((uint32_t)hcan->pTxMsg->Data[0]));
-    hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24U) | 
-                                           ((uint32_t)hcan->pTxMsg->Data[6] << 16U) |
-                                           ((uint32_t)hcan->pTxMsg->Data[5] << 8U) |
-                                           ((uint32_t)hcan->pTxMsg->Data[4]));
-  
-    if(hcan->State == HAL_CAN_STATE_BUSY_RX) 
+    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));
+
+    /* Change CAN state */
+    switch(hcan->State)
     {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
+      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;
     }
-    else
-    {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_BUSY_TX;
-    }
-    
+
     /* Set CAN error code to none */
     hcan->ErrorCode = HAL_CAN_ERROR_NONE;
-    
+
     /* Process Unlocked */
     __HAL_UNLOCK(hcan);
-    
-    /* Enable Error warning Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
-    
-    /* Enable Error passive Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
-    
-    /* Enable Bus-off Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
-    
-    /* Enable Last error code Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
-    
-    /* Enable Error Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
-    
-    /* Enable Transmit mailbox empty Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_TME);
-    
+
     /* 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  );
   }
   else
   {
     /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_ERROR; 
+    hcan->State = HAL_CAN_STATE_ERROR;
 
     /* Return function status */
     return HAL_ERROR;
@@ -772,34 +795,85 @@
 
 /**
   * @brief  Receives a correct CAN frame.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
-  * @param  FIFONumber:    FIFO number.
-  * @param  Timeout:       Timeout duration.
+  * @param  FIFONumber    FIFO number.
+  * @param  Timeout       Timeout duration.
   * @retval HAL status
-  * @retval None
   */
 HAL_StatusTypeDef HAL_CAN_Receive(CAN_HandleTypeDef* hcan, uint8_t FIFONumber, uint32_t Timeout)
 {
-  uint32_t tickstart = 0;
-   
+  uint32_t tickstart = 0U;
+  CanRxMsgTypeDef* pRxMsg = NULL;
+
   /* Check the parameters */
   assert_param(IS_CAN_FIFO(FIFONumber));
-  
+
   /* Process locked */
   __HAL_LOCK(hcan);
-  
-  if(hcan->State == HAL_CAN_STATE_BUSY_TX) 
+
+  /* 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)))
   {
-    /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
+    /* Process unlocked */
+    __HAL_UNLOCK(hcan);
+
+    return HAL_BUSY;
+  }
+
+  /* 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)))
+  {
+    /* Process unlocked */
+    __HAL_UNLOCK(hcan);
+
+    return HAL_BUSY;
   }
-  else
+
+  /* Change CAN state */
+  if (FIFONumber == CAN_FIFO0)
   {
-    /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_BUSY_RX;
+    switch(hcan->State)
+    {
+      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;
+    }
+  }
+
   /* Get tick */
   tickstart = HAL_GetTick();   
   
@@ -809,41 +883,54 @@
     /* Check for the Timeout */
     if(Timeout != HAL_MAX_DELAY)
     {
-      if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+      if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
       {
         hcan->State = HAL_CAN_STATE_TIMEOUT;
+
         /* Process unlocked */
         __HAL_UNLOCK(hcan);
+
         return HAL_TIMEOUT;
       }
     }
   }
-  
+
+  /* Set RxMsg pointer */
+  if(FIFONumber == CAN_FIFO0)
+  {
+    pRxMsg = hcan->pRxMsg;
+  }
+  else /* FIFONumber == CAN_FIFO1 */
+  {
+    pRxMsg = hcan->pRx1Msg;
+  }
+
   /* Get the Id */
-  hcan->pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
-  if (hcan->pRxMsg->IDE == CAN_ID_STD)
+  pRxMsg->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
+  if (pRxMsg->IDE == CAN_ID_STD)
   {
-    hcan->pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
+    pRxMsg->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_TI0R_STID_Pos;
   }
   else
   {
-    hcan->pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
+    pRxMsg->ExtId = (0xFFFFFFF8U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_EXID_Pos;
   }
-  
-  hcan->pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
+  pRxMsg->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_RTR_Pos;
   /* Get the DLC */
-  hcan->pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
+  pRxMsg->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_DLC_Pos;
   /* Get the FMI */
-  hcan->pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
+  pRxMsg->FMI = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_FMI_Pos;
+  /* Get the FIFONumber */
+  pRxMsg->FIFONumber = FIFONumber;
   /* Get the data field */
-  hcan->pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
-  hcan->pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
-  hcan->pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
-  hcan->pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
-  hcan->pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
-  hcan->pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
-  hcan->pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
-  hcan->pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
+  pRxMsg->Data[0] = (CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA0_Pos;
+  pRxMsg->Data[1] = (CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA1_Pos;
+  pRxMsg->Data[2] = (CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA2_Pos;
+  pRxMsg->Data[3] = (CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA3_Pos;
+  pRxMsg->Data[4] = (CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA4_Pos;
+  pRxMsg->Data[5] = (CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA5_Pos;
+  pRxMsg->Data[6] = (CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA6_Pos;
+  pRxMsg->Data[7] = (CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA7_Pos;
   
   /* Release the FIFO */
   if(FIFONumber == CAN_FIFO0)
@@ -856,16 +943,43 @@
     /* Release FIFO1 */
     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO1);
   }
-  
-  if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
+
+  /* Change CAN state */
+  if (FIFONumber == CAN_FIFO0)
   {
-    /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_BUSY_TX;
+    switch(hcan->State)
+    {
+      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;
+    }
   }
-  else
+  else /* FIFONumber == CAN_FIFO1 */
   {
-    /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_READY;
+    switch(hcan->State)
+    {
+      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;
+    }
   }
   
   /* Process unlocked */
@@ -877,69 +991,108 @@
 
 /**
   * @brief  Receives a correct CAN frame.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
-  * @param  FIFONumber:    FIFO number.
+  * @param  FIFONumber    FIFO number.
   * @retval HAL status
-  * @retval None
   */
 HAL_StatusTypeDef HAL_CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
 {
   /* Check the parameters */
   assert_param(IS_CAN_FIFO(FIFONumber));
-  
-  if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_TX))
+
+  /* Process locked */
+  __HAL_LOCK(hcan);
+
+  /* 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)))
   {
-    /* Process locked */
-    __HAL_LOCK(hcan);
-  
-    if(hcan->State == HAL_CAN_STATE_BUSY_TX) 
-    {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
-    }
-    else
-    {
-      /* Change CAN state */
-      hcan->State = HAL_CAN_STATE_BUSY_RX;
-    }
-    
-    /* Set CAN error code to none */
-    hcan->ErrorCode = HAL_CAN_ERROR_NONE;
-    
-    /* Enable Error warning Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
-      
-    /* Enable Error passive Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
-      
-    /* Enable Bus-off Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
-      
-    /* Enable Last error code Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
-      
-    /* Enable Error Interrupt */
-    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
+    /* Process unlocked */
+    __HAL_UNLOCK(hcan);
+
+    return HAL_BUSY;
+  }
 
+  /* 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)))
+  {
     /* Process unlocked */
     __HAL_UNLOCK(hcan);
 
-    if(FIFONumber == CAN_FIFO0)
+    return HAL_BUSY;
+  }
+
+  /* Change CAN state */
+  if (FIFONumber == CAN_FIFO0)
+  {
+    switch(hcan->State)
     {
-      /* Enable FIFO 0 message pending Interrupt */
-      __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
+      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
+  }
+  else /* FIFONumber == CAN_FIFO1 */
+  {
+    switch(hcan->State)
     {
-      /* Enable FIFO 1 message pending Interrupt */
-      __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP1);
+      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;
     }
-    
+  }
+
+  /* Set CAN error code to none */
+  hcan->ErrorCode = HAL_CAN_ERROR_NONE;
+
+  /* Enable interrupts: */
+  /*  - Enable Error warning Interrupt */
+  /*  - Enable Error passive Interrupt */
+  /*  - Enable Bus-off Interrupt */
+  /*  - Enable Last error code Interrupt */
+  /*  - Enable Error Interrupt */
+  __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG |
+                            CAN_IT_EPV |
+                            CAN_IT_BOF |
+                            CAN_IT_LEC |
+                            CAN_IT_ERR);
+
+  /* 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);
   }
   else
   {
-    return HAL_BUSY;
+    /* Enable FIFO 1 overrun and message pending Interrupt */
+    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
   }
   
   /* Return function status */
@@ -948,7 +1101,7 @@
 
 /**
   * @brief  Enters the Sleep (low power) mode.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.
   * @retval HAL status.
   */
@@ -963,10 +1116,13 @@
   hcan->State = HAL_CAN_STATE_BUSY; 
     
   /* Request Sleep mode */
-   hcan->Instance->MCR = (((hcan->Instance->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
+  MODIFY_REG(hcan->Instance->MCR,
+             CAN_MCR_INRQ       ,
+             CAN_MCR_SLEEP       );
    
   /* Sleep mode status */
-  if ((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
+  if (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
+      HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
   {
     /* Process unlocked */
     __HAL_UNLOCK(hcan);
@@ -979,7 +1135,8 @@
   tickstart = HAL_GetTick();   
   
   /* Wait the acknowledge */
-  while((hcan->Instance->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) != CAN_MSR_SLAK)
+  while (HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_SLAK) ||
+         HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)   )
   {
     if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
     {
@@ -1003,7 +1160,7 @@
 /**
   * @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
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.
   * @retval HAL status.
   */
@@ -1018,23 +1175,26 @@
   hcan->State = HAL_CAN_STATE_BUSY;  
  
   /* Wake up request */
-  hcan->Instance->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
+  CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP);
     
   /* Get tick */
   tickstart = HAL_GetTick();   
   
   /* Sleep mode status */
-  while((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
+  while(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
   {
     if((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE)
     {
       hcan->State= HAL_CAN_STATE_TIMEOUT;
+
       /* Process unlocked */
       __HAL_UNLOCK(hcan);
+
       return HAL_TIMEOUT;
     }
   }
-  if((hcan->Instance->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)
+
+  if(HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_SLAK))
   {
     /* Process unlocked */
     __HAL_UNLOCK(hcan);
@@ -1055,27 +1215,67 @@
 
 /**
   * @brief  Handles CAN interrupt request  
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @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)
 {
+  uint32_t errorcode = HAL_CAN_ERROR_NONE;
+
+  /* Check Overrun flag for FIFO0 */
+  if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV0))    &&
+     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV0)))
+  {
+    /* Set CAN error code to FOV0 error */
+    errorcode |= HAL_CAN_ERROR_FOV0;
+
+    /* Clear FIFO0 Overrun Flag */
+    __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0);
+  }
+
+  /* Check Overrun flag for FIFO1 */
+  if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_FOV1))    &&
+     (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FOV1)))
+  {
+    /* Set CAN error code to FOV1 error */
+    errorcode |= HAL_CAN_ERROR_FOV1;
+
+    /* Clear FIFO1 Overrun Flag */
+    __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1);
+  }
+
   /* Check End of transmission flag */
   if(__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_TME))
   {
+    /* Check Transmit request completion status */
     if((__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_0)) ||
        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_1)) ||
        (__HAL_CAN_TRANSMIT_STATUS(hcan, CAN_TXMAILBOX_2)))
     {
-      /* Call transmit function */
-      CAN_Transmit_IT(hcan);
+      /* Check Transmit success */
+      if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK0)) ||
+         (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK1)) ||
+         (__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_TXOK2)))
+      {
+        /* Call transmit function */
+        CAN_Transmit_IT(hcan);
+      }
+      else /* Transmit failure */
+      {
+        /* Set CAN error code to TXFAIL error */
+        errorcode |= HAL_CAN_ERROR_TXFAIL;
+      }
+
+      /* 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);
     }
   }
   
   /* Check End of reception flag for FIFO0 */
   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP0)) &&
-     (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0))
+     (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO0) != 0U))
   {
     /* Call receive function */
     CAN_Receive_IT(hcan, CAN_FIFO0);
@@ -1083,12 +1283,15 @@
   
   /* Check End of reception flag for FIFO1 */
   if((__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_FMP1)) &&
-     (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0))
+     (__HAL_CAN_MSG_PENDING(hcan, CAN_FIFO1) != 0U))
   {
     /* Call receive function */
     CAN_Receive_IT(hcan, CAN_FIFO1);
   }
   
+  /* Set error code in handle */
+  hcan->ErrorCode |= errorcode;
+
   /* Check Error Warning Flag */
   if((__HAL_CAN_GET_FLAG(hcan, CAN_FLAG_EWG))    &&
      (__HAL_CAN_GET_IT_SOURCE(hcan, CAN_IT_EWG)) &&
@@ -1106,7 +1309,7 @@
   {
     /* Set CAN error code to EPV error */
     hcan->ErrorCode |= HAL_CAN_ERROR_EPV;
-    /* No need for clear of Error Passive Flag as read-only */
+    /* No need for clear of Error Passive Flag as read-only */ 
   }
   
   /* Check Bus-Off Flag */
@@ -1155,16 +1358,40 @@
     }
 
     /* Clear Last error code Flag */ 
-    hcan->Instance->ESR &= ~(CAN_ESR_LEC);
+    CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC);
   }
 
   /* Call the Error call Back in case of Errors */
   if(hcan->ErrorCode != HAL_CAN_ERROR_NONE)
   {
     /* Clear ERRI Flag */ 
-    hcan->Instance->MSR |= CAN_MSR_ERRI; 
+    SET_BIT(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  );
+
     /* Call Error callback function */
     HAL_CAN_ErrorCallback(hcan);
   }  
@@ -1172,7 +1399,7 @@
 
 /**
   * @brief  Transmission  complete callback in non blocking mode 
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.
   * @retval None
   */
@@ -1188,7 +1415,7 @@
 
 /**
   * @brief  Transmission  complete callback in non blocking mode 
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.
   * @retval None
   */
@@ -1204,7 +1431,7 @@
 
 /**
   * @brief  Error CAN callback.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.
   * @retval None
   */
@@ -1240,7 +1467,7 @@
 
 /**
   * @brief  return the CAN state
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.
   * @retval HAL state
   */
@@ -1252,7 +1479,7 @@
 
 /**
   * @brief  Return the CAN error code
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.
   * @retval CAN Error Code
   */
@@ -1274,9 +1501,10 @@
  *
  * @{
  */
+
 /**
   * @brief  Initiates and transmits a CAN frame message.
-  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
   * @retval HAL status
   */
@@ -1287,33 +1515,36 @@
   
   if(hcan->State == HAL_CAN_STATE_BUSY_TX)
   {   
-    /* Disable Error warning Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
-    
-    /* Disable Error passive Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
-    
-    /* Disable Bus-off Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
-    
-    /* Disable Last error code Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
-    
-    /* Disable Error Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR);
+    /* 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 );
   }
-  
-  if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
+
+  /* Change CAN state */
+  switch(hcan->State)
   {
-    /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_BUSY_RX;
+    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;
   }
-  else
-  {
-    /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_READY;
-  }
-  
+
   /* Transmission complete callback */ 
   HAL_CAN_TxCpltCallback(hcan);
   
@@ -1322,84 +1553,122 @@
 
 /**
   * @brief  Receives a correct CAN frame.
-  * @param  hcan:       Pointer to a CAN_HandleTypeDef structure that contains
+  * @param  hcan       Pointer to a CAN_HandleTypeDef structure that contains
   *         the configuration information for the specified CAN.  
-  * @param  FIFONumber: Specify the FIFO number    
+  * @param  FIFONumber Specify the FIFO number    
   * @retval HAL status
   * @retval None
   */
 static HAL_StatusTypeDef CAN_Receive_IT(CAN_HandleTypeDef* hcan, uint8_t FIFONumber)
 {
+  CanRxMsgTypeDef* pRxMsg = NULL;
+
+  /* Set RxMsg pointer */
+  if(FIFONumber == CAN_FIFO0)
+  {
+    pRxMsg = hcan->pRxMsg;
+  }
+  else /* FIFONumber == CAN_FIFO1 */
+  {
+    pRxMsg = hcan->pRx1Msg;
+  }
+
   /* Get the Id */
-  hcan->pRxMsg->IDE = (uint8_t)0x04U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
-  if (hcan->pRxMsg->IDE == CAN_ID_STD)
+  pRxMsg->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
+  if (pRxMsg->IDE == CAN_ID_STD)
   {
-    hcan->pRxMsg->StdId = 0x000007FFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 21U);
+    pRxMsg->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_TI0R_STID_Pos;
   }
   else
   {
-    hcan->pRxMsg->ExtId = 0x1FFFFFFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RIR >> 3U);
+    pRxMsg->ExtId = (0xFFFFFFF8U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_EXID_Pos;
   }
-  
-  hcan->pRxMsg->RTR = (uint8_t)0x02U & hcan->Instance->sFIFOMailBox[FIFONumber].RIR;
+  pRxMsg->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[FIFONumber].RIR) >> CAN_RI0R_RTR_Pos;
   /* Get the DLC */
-  hcan->pRxMsg->DLC = (uint8_t)0x0FU & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR;
+  pRxMsg->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_DLC_Pos;
   /* Get the FMI */
-  hcan->pRxMsg->FMI = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDTR >> 8U);
+  pRxMsg->FMI = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[FIFONumber].RDTR) >> CAN_RDT0R_FMI_Pos;
+  /* Get the FIFONumber */
+  pRxMsg->FIFONumber = FIFONumber;
   /* Get the data field */
-  hcan->pRxMsg->Data[0] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR;
-  hcan->pRxMsg->Data[1] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 8U);
-  hcan->pRxMsg->Data[2] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 16U);
-  hcan->pRxMsg->Data[3] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDLR >> 24U);
-  hcan->pRxMsg->Data[4] = (uint8_t)0xFFU & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR;
-  hcan->pRxMsg->Data[5] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 8U);
-  hcan->pRxMsg->Data[6] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 16U);
-  hcan->pRxMsg->Data[7] = (uint8_t)0xFFU & (hcan->Instance->sFIFOMailBox[FIFONumber].RDHR >> 24U);
+  pRxMsg->Data[0] = (CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA0_Pos;
+  pRxMsg->Data[1] = (CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA1_Pos;
+  pRxMsg->Data[2] = (CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA2_Pos;
+  pRxMsg->Data[3] = (CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[FIFONumber].RDLR) >> CAN_RDL0R_DATA3_Pos;
+  pRxMsg->Data[4] = (CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA4_Pos;
+  pRxMsg->Data[5] = (CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA5_Pos;
+  pRxMsg->Data[6] = (CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA6_Pos;
+  pRxMsg->Data[7] = (CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[FIFONumber].RDHR) >> CAN_RDH0R_DATA7_Pos;
+
   /* Release the FIFO */
   /* Release FIFO0 */
   if (FIFONumber == CAN_FIFO0)
   {
     __HAL_CAN_FIFO_RELEASE(hcan, CAN_FIFO0);
     
-    /* Disable FIFO 0 message pending Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP0);
+    /* 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 message pending Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FMP1);
+    /* Disable FIFO 1 overrun and message pending Interrupt */
+    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_FOV1 | CAN_IT_FMP1);
   }
   
-  if(hcan->State == HAL_CAN_STATE_BUSY_RX)
+  if((hcan->State == HAL_CAN_STATE_BUSY_RX0) || (hcan->State == HAL_CAN_STATE_BUSY_RX1))
   {   
-    /* Disable Error warning Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EWG);
-    
-    /* Disable Error passive Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_EPV);
-    
-    /* Disable Bus-off Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_BOF);
-    
-    /* Disable Last error code Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_LEC);
-    
-    /* Disable Error Interrupt */
-    __HAL_CAN_DISABLE_IT(hcan, CAN_IT_ERR);
+    /* 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 );
   }
-  
-  if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) 
+
+  /* Change CAN state */
+  if (FIFONumber == CAN_FIFO0)
   {
-    /* Disable CAN state */
-    hcan->State = HAL_CAN_STATE_BUSY_TX;
+    switch(hcan->State)
+    {
+      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;
+    }
   }
-  else
+  else /* FIFONumber == CAN_FIFO1 */
   {
-    /* Change CAN state */
-    hcan->State = HAL_CAN_STATE_READY;
+    switch(hcan->State)
+    {
+      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;
+    }
   }
 
   /* Receive complete callback */ 
@@ -1408,6 +1677,7 @@
   /* Return function status */
   return HAL_OK;
 }
+
 /**
   * @}
   */