mbed library sources, include can_api for nucleo-f091rc

Dependents:   CanNucleoF0_example

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
ptpaterson
Date:
Thu Jan 07 05:49:05 2016 +0000
Parent:
644:612d6aa9e717
Commit message:
corrected freeze on CAN_RECEIVE_IT

Changed in this revision

targets/hal/TARGET_STM/TARGET_STM32F0/can_api.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 612d6aa9e717 -r 13c87cbecd54 targets/hal/TARGET_STM/TARGET_STM32F0/can_api.cpp
--- a/targets/hal/TARGET_STM/TARGET_STM32F0/can_api.cpp	Mon Jan 04 06:10:26 2016 +0000
+++ b/targets/hal/TARGET_STM/TARGET_STM32F0/can_api.cpp	Thu Jan 07 05:49:05 2016 +0000
@@ -95,64 +95,53 @@
  * it freezes upon receiving a message (write is fine!) supports
  * my guess.
  */
-#define USE_RECEIVE_IT 0
+
 
+/* holder for objects that need to be global */
+CAN_HandleTypeDef hcan;
 static PinName pinRd;
 static PinName pinTd;
 
 /**
- * @brief
- * @note
- * @param
- * @retval
- */
-void
-can_init (can_t    *obj,
-          PinName   rd,
-          PinName   td)
-{       
+  * @note
+  * @param
+  * @retval none
+  */
+void can_init (can_t    *obj, PinName   rd, PinName   td)
+{
     // DEBUG
     printf("api: can_init\r\n");
-    
-    /* file scope so that they can be referenced in the MSP functions */
+
+    /* set global pin values for MSP functions */
     pinRd = rd;
     pinTd = td;
 
-    /* only one CAN controller for STM32F0, otherwise need to figure it out here */
-#if USE_RECEIVE_IT
-    single_can_controller = obj; /* this is so we can cheat and call globally*/
-#endif
-    obj->index = 0;
+    /* Set the peripheral pointer */
+    hcan.Instance = ((CAN_TypeDef*)CAN_BASE);
 
-    /* initialize the static data */
-    static CAN_HandleTypeDef hcan;
-    obj->hcan = &hcan;
-    obj->hcan->Instance = ((CAN_TypeDef *) CAN_BASE);
-
+    /* initialize the mail boxes */
     static CanTxMsgTypeDef txMessage;
     static CanRxMsgTypeDef rxMessage;
-    obj->hcan->pTxMsg = &txMessage;
-    obj->hcan->pRxMsg = &rxMessage;
+    hcan.pTxMsg = &txMessage;
+    hcan.pRxMsg = &rxMessage;
 
-    /* set operation mode */
-    obj->hcan->Init.TTCM = DISABLE;
-    obj->hcan->Init.ABOM = ENABLE;
-    obj->hcan->Init.AWUM = DISABLE;
-    obj->hcan->Init.NART = DISABLE;
-    obj->hcan->Init.RFLM = DISABLE;
-    obj->hcan->Init.TXFP = DISABLE;
-    obj->hcan->Init.Mode = CAN_MODE_NORMAL;
+    /* Initialize the CAN peripheral */
+    hcan.Init.TTCM = DISABLE;
+    hcan.Init.ABOM = ENABLE;
+    hcan.Init.AWUM = DISABLE;
+    hcan.Init.NART = DISABLE;
+    hcan.Init.RFLM = DISABLE;
+    hcan.Init.TXFP = DISABLE;
+    hcan.Init.Mode = CAN_MODE_NORMAL;
 
-    /* set th default frequency
-     * 125kbps bit rate (default)
-     * APB1 peripheral clock = 36000000Hz
-     */
-    obj->hcan->Init.Prescaler = 18;      // number of time quanta = 36000000/18/125000 = 16
-    obj->hcan->Init.SJW = CAN_SJW_1TQ;
-    obj->hcan->Init.BS1 = CAN_BS1_11TQ;  // sample point at (1 + 11) / 16 * 100 = 75%
-    obj->hcan->Init.BS2 = CAN_BS2_4TQ;
+    // 125kbps bit rate (default)
+    // APB1 peripheral clock = 48000000Hz
+    hcan.Init.Prescaler = 24;     // number of time quanta = 48000000/24/125000 = 16
+    hcan.Init.SJW = CAN_SJW_1TQ;
+    hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
+    hcan.Init.BS2 = CAN_BS2_4TQ;
 
-    int status = HAL_CAN_Init (obj->hcan);
+    int status = HAL_CAN_Init (&hcan);
     if (status != HAL_OK) {
         printf("api: can_init: HAL_CAN_INIT issue\r\n");
     }
@@ -172,7 +161,7 @@
 void
 can_free (can_t *obj)
 {
-    HAL_CAN_DeInit (obj->hcan);
+    HAL_CAN_DeInit (&hcan);
 }
 
 /**
@@ -181,55 +170,54 @@
  * @param
  * @retval
  */
-int
-can_frequency(can_t    *obj,
-              int       hz)
+int can_frequency(can_t *obj, int hz)
 {
     HAL_NVIC_DisableIRQ(CEC_CAN_IRQn);
 
-    // APB1 peripheral clock = 36000000Hz
-
+    // APB1 peripheral clock = 48000000Hz
     switch(hz) {
         case 1000000:
             // 1000kbps bit rate
-            obj->hcan->Init.Prescaler = 3;      // number of time quanta = 36000000/3/1000000 = 12
-            obj->hcan->Init.SJW = CAN_SJW_1TQ;
-            obj->hcan->Init.BS1 = CAN_BS1_8TQ;  // sample point at: (1 + 8) / 12 * 100 = 75%
-            obj->hcan->Init.BS2 = CAN_BS2_3TQ;
+            hcan.Init.Prescaler = 4;      // number of time quanta = 48000000/4/1000000 = 12
+            hcan.Init.SJW = CAN_SJW_1TQ;
+            hcan.Init.BS1 = CAN_BS1_8TQ;  // sample point at: (1 + 8) / 12 * 100 = 75%
+            hcan.Init.BS2 = CAN_BS2_3TQ;
             break;
 
         case 500000:
             // 500kbps bit rate
-            obj->hcan->Init.Prescaler = 6;      // number of time quanta = 36000000/6/500000 = 12
-            obj->hcan->Init.SJW = CAN_SJW_1TQ;
-            obj->hcan->Init.BS1 = CAN_BS1_8TQ;  // sample point at: (1 + 8) / 12 * 100 = 75%
-            obj->hcan->Init.BS2 = CAN_BS2_3TQ;
+            hcan.Init.Prescaler = 8;      // number of time quanta = 48000000/8/500000 = 12
+            hcan.Init.SJW = CAN_SJW_1TQ;
+            hcan.Init.BS1 = CAN_BS1_8TQ;  // sample point at: (1 + 8) / 12 * 100 = 75%
+            hcan.Init.BS2 = CAN_BS2_3TQ;
             break;
 
         case 250000:
             // 250kbps
-            obj->hcan->Init.Prescaler = 9;      // number of time quanta = 36000000/9/250000 = 16
-            obj->hcan->Init.SJW = CAN_SJW_1TQ;
-            obj->hcan->Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
-            obj->hcan->Init.BS2 = CAN_BS2_4TQ;
+            hcan.Init.Prescaler = 12;     // number of time quanta = 48000000/12/250000 = 16
+            hcan.Init.SJW = CAN_SJW_1TQ;
+            hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
+            hcan.Init.BS2 = CAN_BS2_4TQ;
             break;
 
         case 125000:
             // 125kbps
-            obj->hcan->Init.Prescaler = 18;     // number of time quanta = 36000000/18/125000 = 16
-            obj->hcan->Init.SJW = CAN_SJW_1TQ;
-            obj->hcan->Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
-            obj->hcan->Init.BS2 = CAN_BS2_4TQ;
+            hcan.Init.Prescaler = 24;     // number of time quanta = 48000000/24/125000 = 16
+            hcan.Init.SJW = CAN_SJW_1TQ;
+            hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
+            hcan.Init.BS2 = CAN_BS2_4TQ;
             break;
 
         default:
             // 125kbps (default)
-            obj->hcan->Init.Prescaler = 18;     // number of time quanta = 36000000/18/125000 = 16
-            obj->hcan->Init.SJW = CAN_SJW_1TQ;
-            obj->hcan->Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
-            obj->hcan->Init.BS2 = CAN_BS2_4TQ;
+            hcan.Init.Prescaler = 24;     // number of time quanta = 48000000/24/125000 = 16
+            hcan.Init.SJW = CAN_SJW_1TQ;
+            hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
+            hcan.Init.BS2 = CAN_BS2_4TQ;
+            break;
     }
-    HAL_CAN_Init(obj->hcan);
+
+    HAL_CAN_Init(&hcan);
 
     /* HAL_CAN_INIT will call HAL_CAN_MspInit, which will init the interupts */
 
@@ -241,93 +229,83 @@
  * and used later in HAL_CAN_RxCpltCallback()
  */
 
-#if USE_RECEIVE_IT
-
-    #define CAN_MESSAGE_QUEUE_SIZE 10
-    
-    /**
-     * @brief Holder for obj* when not passed to function  
-     * @note need this to cheat for now while we don't have a way to implement
-     * multiple CAN controllers
-     */
-    static can_t *single_can_controller;
-    
-    /**
-     * @brief Queue to hold several incomming messages while we wait for the user
-     * to call for them.
-     * @note This is only necessary now, because the STM32 HAL handles the can
-     * receive FIFO by writing to the CAN_HandleTypeDef and popping from the built
-     * in queue.
-     */
-    typedef struct {
-        int    next;
-        unsigned int    contain_mask;
-        CanRxMsgTypeDef queue[CAN_MESSAGE_QUEUE_SIZE];
-    } can_message_queue;
-    
-    static can_message_queue message_queues[CAN_NUM];
-    
-    /**
-     * @brief Adds one message to the queue
-     * @note sends indication of overflow if it happens but overwites anyway
-     */
-    static int message_enqueue(can_t           *obj,
-                               CanRxMsgTypeDef *msg)
-    {    
-        int result = 1;
-    
-        int next = message_queues[obj->index].next;
-        if (++next >= CAN_MESSAGE_QUEUE_SIZE)
-            next = 0;
-    
-        if (message_queues[obj->index].contain_mask & (1 << next))
-            result = 0; /* overflow */
-    
-        message_queues[obj->index].queue[next]   = *msg;
-        message_queues[obj->index].next          = next;
-        message_queues[obj->index].contain_mask |= next;
-    
-        return result;
-    }
-    
-    /**
-     * @brief Pops one message from the queue
-     * @note sends indication of overflow if it happens but overwites anyway
-     */
-    static int message_dequeue(can_t           *obj,
-                               CanRxMsgTypeDef *msg)
-    {
-        int result = 1;
-    
-        int next = message_queues[obj->index].next;
-    
-        if (message_queues[obj->index].contain_mask & (1 << next)) {
-            
-            *msg = message_queues[obj->index].queue[next];
-            message_queues[obj->index].contain_mask &= ~next;
-    
-            if (--next < 0)
-                next = CAN_MESSAGE_QUEUE_SIZE - 1;
-            message_queues[obj->index].next = next;
-    
-        } else {
-            result = 0; /* no current message */
-        }
-    
-        return result;
-    }
-    
-    
-    /** becomes a pointer to the member function Can::_irq_handler */
-    static can_irq_handler irq_handler;
-    
-    /** id is really just a pointer to the Can object
-     * useful for uC's that have multiple CAN devices
-     */
-    static uint32_t can_irq_ids[CAN_NUM] = {0};
+#define CAN_MESSAGE_QUEUE_SIZE 10
 
 
-#endif /* USE_RECEIVE_IT */
+/**
+ * @brief Queue to hold several incomming messages while we wait for the user
+ * to call for them.
+ * @note This is only necessary now, because the STM32 HAL handles the can
+ * receive FIFO by writing to the CAN_HandleTypeDef and popping from the built
+ * in queue.
+ */
+typedef struct {
+    int    next;
+    unsigned int    contain_mask;
+    CanRxMsgTypeDef queue[CAN_MESSAGE_QUEUE_SIZE];
+} can_message_queue;
+
+static can_message_queue message_queues[CAN_NUM];
+
+/**
+ * @brief Adds one message to the queue
+ * @note sends indication of overflow if it happens but overwites anyway
+ */
+static int message_enqueue(can_t           *obj,
+                           CanRxMsgTypeDef *msg)
+{
+    int result = 1;
+
+    int next = message_queues[obj->index].next;
+    if (++next >= CAN_MESSAGE_QUEUE_SIZE)
+        next = 0;
+
+    if (message_queues[obj->index].contain_mask & (1 << next))
+        result = 0; /* overflow */
+
+    message_queues[obj->index].queue[next]   = *msg;
+    message_queues[obj->index].next          = next;
+    message_queues[obj->index].contain_mask |= next;
+
+    return result;
+}
+
+/**
+ * @brief Pops one message from the queue
+ * @note sends indication of overflow if it happens but overwites anyway
+ */
+static int message_dequeue(can_t           *obj,
+                           CanRxMsgTypeDef *msg)
+{
+    int result = 1;
+
+    int next = message_queues[obj->index].next;
+
+    if (message_queues[obj->index].contain_mask & (1 << next)) {
+
+        *msg = message_queues[obj->index].queue[next];
+        message_queues[obj->index].contain_mask &= ~next;
+
+        if (--next < 0)
+            next = CAN_MESSAGE_QUEUE_SIZE - 1;
+        message_queues[obj->index].next = next;
+
+    } else {
+        result = 0; /* no current message */
+    }
+
+    return result;
+}
+
+/** becomes a pointer to the member function Can::_irq_handler */
+static can_irq_handler irq_handler;
+
+/** id is really just a pointer to the Can object
+ * useful for uC's that have multiple CAN devices
+ */
+static uint32_t can_irq_ids[CAN_NUM] = {0};
+
+
 
 /**
  * @brief
@@ -340,20 +318,18 @@
               can_irq_handler   handler,
               uint32_t          id)
 {
-    #if USE_RECEIVE_IT
-        // DEBUG
-        printf("api: can_irq_init\r\n");
-    
-        irq_handler = handler;
-        can_irq_ids[obj->index] = id;
-    
-        message_queues[obj->index].contain_mask = 0;
-        message_queues[obj->index].next = CAN_MESSAGE_QUEUE_SIZE - 1;
-    
-        if (HAL_CAN_Receive_IT (obj->hcan, CAN_FIFO0) != HAL_OK) {
-            printf("api: can_irq_init:  receive failed\r\n");
-        }
-    #endif /* USE_RECEIVE_IT */
+    // DEBUG
+    printf("api: can_irq_init\r\n");
+
+    irq_handler = handler;
+    can_irq_ids[obj->index] = id;
+
+    message_queues[obj->index].contain_mask = 0;
+    message_queues[obj->index].next = CAN_MESSAGE_QUEUE_SIZE - 1;
+
+    if (HAL_CAN_Receive_IT (&hcan, CAN_FIFO0) != HAL_OK) {
+        printf("api: can_irq_init:  receive failed\r\n");
+    }
 }
 
 
@@ -397,23 +373,23 @@
 {
     // DEBUG
     printf("api: can_write\r\n");
-    
+
     if (msg.format == CANStandard) {
-        obj->hcan->pTxMsg->StdId = msg.id;
-        obj->hcan->pTxMsg->ExtId = 0x00;
+        hcan.pTxMsg->StdId = msg.id;
+        hcan.pTxMsg->ExtId = 0x00;
     } else {
-        obj->hcan->pTxMsg->StdId = 0x00;
-        obj->hcan->pTxMsg->ExtId = msg.id;
+        hcan.pTxMsg->StdId = 0x00;
+        hcan.pTxMsg->ExtId = msg.id;
     }
 
-    obj->hcan->pTxMsg->RTR = msg.type == CANData ? CAN_RTR_DATA : CAN_RTR_REMOTE;
-    obj->hcan->pTxMsg->IDE = msg.format == CANStandard ? CAN_ID_STD : CAN_ID_EXT;
-    obj->hcan->pTxMsg->DLC = msg.len;
+    hcan.pTxMsg->RTR = msg.type == CANData ? CAN_RTR_DATA : CAN_RTR_REMOTE;
+    hcan.pTxMsg->IDE = msg.format == CANStandard ? CAN_ID_STD : CAN_ID_EXT;
+    hcan.pTxMsg->DLC = msg.len;
 
-    memcpy(obj->hcan->pTxMsg->Data, &(msg.data), msg.len);
+    memcpy(hcan.pTxMsg->Data, &(msg.data), msg.len);
 
     int result = 1;
-    if (HAL_CAN_Transmit(obj->hcan, 10) != HAL_OK) {
+    if (HAL_CAN_Transmit(&hcan, 5) != HAL_OK) {
         result = 0;
     }
 
@@ -432,47 +408,22 @@
           CAN_Message  *msg,
           int           handle)
 {
+
     int result = 0;
-    
-    #if USE_RECEIVE_IT
-        CanRxMsgTypeDef popMessage;
-        if (message_dequeue (obj, &popMessage)) {
-            
-            msg->id     = popMessage.IDE == CAN_ID_STD   ? popMessage.StdId : popMessage.ExtId;
-            msg->type   = popMessage.RTR == CAN_RTR_DATA ? CANData          : CANRemote;
-            msg->format = popMessage.IDE == CAN_ID_STD   ? CANStandard      : CANExtended;
-            msg->len    = popMessage.DLC;
-        
-            memcpy(msg->data, &(popMessage.Data), msg->len);
-            
-            result = msg->len;
-        }
-    #else
-        CanRxMsgTypeDef *popMessage = obj->hcan->pRxMsg;
-        HAL_StatusTypeDef status = HAL_CAN_Receive (obj->hcan, CAN_FIFO0, 10);
-        if (status == HAL_OK) {
-            printf("api: can_read: HAL_OK\r\n");
-            
-            msg->id     = popMessage->IDE == CAN_ID_STD   ? popMessage->StdId : popMessage->ExtId;
-            msg->type   = popMessage->RTR == CAN_RTR_DATA ? CANData          : CANRemote;
-            msg->format = popMessage->IDE == CAN_ID_STD   ? CANStandard      : CANExtended;
-            msg->len    = popMessage->DLC;
-        
-            memcpy(msg->data, &(popMessage->Data), msg->len);
-            
-            result = msg->len;
-            
-            
-        } else if (status == HAL_ERROR) {
-            printf("api: can_read: HAL_ERROR\r\n");
-        } else if (status == HAL_BUSY) {
-            printf("api: can_read: HAL_BUSY\r\n");
-        } else if (status == HAL_TIMEOUT) {
-        } else {
-            printf("api: can_read: UNKNOWN STATUS!!!!!!!\r\n");            
-        }
-    #endif /* USE_RECEIVE_IT */
-    
+
+    CanRxMsgTypeDef popMessage;
+    if (message_dequeue (obj, &popMessage)) {
+
+        msg->id     = popMessage.IDE == CAN_ID_STD   ? popMessage.StdId : popMessage.ExtId;
+        msg->type   = popMessage.RTR == CAN_RTR_DATA ? CANData          : CANRemote;
+        msg->format = popMessage.IDE == CAN_ID_STD   ? CANStandard      : CANExtended;
+        msg->len    = popMessage.DLC;
+
+        memcpy(msg->data, &(popMessage.Data), msg->len);
+
+        result = msg->len;
+    }
+
     return result;
 }
 
@@ -494,28 +445,28 @@
             break;
 
         case MODE_NORMAL:
-            obj->hcan->Init.Mode = CAN_MODE_NORMAL;
+            hcan.Init.Mode = CAN_MODE_NORMAL;
             break;
 
         case MODE_SILENT:
-            obj->hcan->Init.Mode = CAN_MODE_SILENT;
+            hcan.Init.Mode = CAN_MODE_SILENT;
             break;
 
         case MODE_TEST_GLOBAL:
-            obj->hcan->Init.Mode = CAN_MODE_LOOPBACK;
+            hcan.Init.Mode = CAN_MODE_LOOPBACK;
             break;
 
         case MODE_TEST_LOCAL:
-            obj->hcan->Init.Mode = CAN_MODE_LOOPBACK;
+            hcan.Init.Mode = CAN_MODE_LOOPBACK;
             break;
 
         case MODE_TEST_SILENT:
-            obj->hcan->Init.Mode = CAN_MODE_SILENT_LOOPBACK;
+            hcan.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
             break;
     }
 
     if (success != HAL_ERROR) {
-        success = HAL_CAN_Init(obj->hcan);
+        success = HAL_CAN_Init(&hcan);
     }
 
     return success;
@@ -547,7 +498,7 @@
     sFilterConfig.FilterActivation = ENABLE;
     sFilterConfig.BankNumber = 0;           // Selects the start bank filter
 
-    return HAL_CAN_ConfigFilter(obj->hcan, &sFilterConfig);
+    return HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
 }
 
 /**
@@ -559,7 +510,7 @@
 void
 can_reset (can_t *obj)
 {
-    __HAL_CAN_RESET_HANDLE_STATE(obj->hcan);
+    __HAL_CAN_RESET_HANDLE_STATE(&hcan);
 }
 
 /**
@@ -571,7 +522,7 @@
 unsigned char
 can_rderror (can_t *obj)
 {
-    return HAL_CAN_GetError(obj->hcan);
+    return HAL_CAN_GetError(&hcan);
 }
 
 /**
@@ -583,7 +534,7 @@
 unsigned char
 can_tderror (can_t *obj)
 {
-    return HAL_CAN_GetError(obj->hcan);
+    return HAL_CAN_GetError(&hcan);
 }
 
 /**
@@ -603,70 +554,66 @@
  * HAL_MSP and other functions
  *=============================================================================
  */
- 
+
 /**
   * @brief  CAN MSP Initialization
   * @param  hcan: CAN handle pointer
   * @retval None
   */
-void
-HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
+void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
 {
-    // DEBUG
-    printf("Msp: HAL_CAN_MspInit\r\n");
-    
-    /* derived from STM32CubeMX */
-
     GPIO_InitTypeDef    GPIO_InitStruct;
-    if (hcan->Instance == ((CAN_TypeDef *) CAN_BASE)) {
-        if ((pinRd == PA_11) && (pinTd == PA_12)) {
-            
-            /* Peripheral clock enable */
-            __CAN_CLK_ENABLE();
+
+    if((pinRd == PA_11) && (pinTd == PA_12)) {
+
+        /* CAN1 Periph clock enable */
+        __CAN_CLK_ENABLE();
 
-            /* Enable GPIO clock */
-            __GPIOA_CLK_ENABLE();
+        /* Enable GPIO clock */
+        __GPIOA_CLK_ENABLE();
+
+        /* CAN1 RX GPIO pin configuration */
+        GPIO_InitStruct.Pin = GPIO_PIN_11;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Pull = GPIO_NOPULL;
+        GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
-            /**CAN GPIO Configuration
-            PA11     ------> CAN_RX
-            PA12     ------> CAN_TX
-            */
-            GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
-            GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-            GPIO_InitStruct.Pull = GPIO_NOPULL;
-            GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
-            GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
-            HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-        } else if ((pinRd == PB_8) && (pinTd == PB_9)) {
-            /* Peripheral clock enable */
-            __CAN_CLK_ENABLE();
+        /* CAN1 TX GPIO pin configuration */
+        GPIO_InitStruct.Pin = GPIO_PIN_12;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Pull = GPIO_NOPULL;
+        GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    } else if((pinRd == PB_8) && (pinTd == PB_9)) {
+        /* CAN1 Periph clock enable */
+        __CAN_CLK_ENABLE();
 
-            /* Enable GPIO clock */
-            __GPIOB_CLK_ENABLE();
+        /* Enable GPIO clock */
+        __GPIOB_CLK_ENABLE();
 
-            /**CAN GPIO Configuration
-            PB8     ------> CAN_RX
-            PB9     ------> CAN_TX
-            */
-            GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
-            GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-            GPIO_InitStruct.Pull = GPIO_NOPULL;
-            GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
-            GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
-            HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-        } else {
-            printf("bad pins defined in CAN class\r\n");   
-        }        
+        /* CAN1 RX GPIO pin configuration */
+        GPIO_InitStruct.Pin = GPIO_PIN_8;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Pull = GPIO_NOPULL;
+        GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
-        #if USE_RECEIVE_IT
-            /* Peripheral interrupt init*/
-            HAL_NVIC_SetPriority(CEC_CAN_IRQn, 0, 0);
-            HAL_NVIC_EnableIRQ(CEC_CAN_IRQn);
-        #endif /* USE_RECEIVE_IT */
-    } else {
-        printf("CAN_HandleTypeDef instance bad\r\n");    
-    }
-
+        /* CAN1 TX GPIO pin configuration */
+        GPIO_InitStruct.Pin = GPIO_PIN_9;
+        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+        GPIO_InitStruct.Pull = GPIO_NOPULL;
+        GPIO_InitStruct.Alternate =  GPIO_AF4_CAN;
+        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    } else
+        return;
+    /* NVIC configuration for CAN1 Reception complete interrupt */
+    HAL_NVIC_SetPriority(CEC_CAN_IRQn, 1, 0);
+    HAL_NVIC_EnableIRQ(CEC_CAN_IRQn);
 }
 
 /**
@@ -677,90 +624,100 @@
   * @param hcan: CAN handle pointer
   * @retval None
   */
-void
-HAL_CAN_MspDeInit (CAN_HandleTypeDef* hcan)
+void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
 {
-    // DEBUG
-    printf("Msp: HAL_CAN_MspDeInit\r\n");
-    
-    /* derived from STM32CubeMX */
+
+    /* Reset peripherals */
 
-    if (hcan->Instance == ((CAN_TypeDef *) CAN_BASE)) {
-        /* Peripheral clock disable */
-        __CAN_CLK_DISABLE();
+    __CAN_FORCE_RESET();
+    __CAN_RELEASE_RESET();
 
-        /* Disable pins*/
-        if ((pinRd == PA_11) && (pinTd == PA_12)) {
-            /**CAN GPIO Configuration
-            PA11     ------> CAN_RX
-            PA12     ------> CAN_TX
-            */
-            HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
-        } else if ((pinRd == PB_8) && (pinTd == PB_9)) {
-            /**CAN GPIO Configuration
-            PB8     ------> CAN_RX
-            PB9     ------> CAN_TX
-            */
-            HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9);
-        } else {}
+    /* Disable peripherals and GPIO Clocks */
+    if((pinRd == PA_11) && (pinTd == PA_12)) {
+        /* De-initialize the CAN1 RX GPIO pin */
+        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11);
+
+        /* De-initialize the CAN1 TX GPIO pin */
+        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12);
+    } else {
+
+        /* De-initialize the CAN1 RX GPIO pin */
+        HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8);
+
+        /* De-initialize the CAN1 TX GPIO pin */
+        HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
     }
 
-    #if USE_RECEIVE_IT
-        /* Disable the NVIC for CAN reception */
-        HAL_NVIC_DisableIRQ(CEC_CAN_IRQn);
-    #endif /* USE_RECEIVE_IT */
+
+    /* Disable the NVIC for CAN reception */
+    HAL_NVIC_DisableIRQ(CEC_CAN_IRQn);
+}
+
+/**
+* @brief  Handles CAN RX0 interrupt request.
+* @param  None
+* @note STM32F0 uses different interrupts than F4
+* @retval None
+*/
+void CEC_CAN_IRQHandler(void)
+{
+    HAL_CAN_IRQHandler(&hcan);
 }
 
 
-#if USE_RECEIVE_IT
-    /**
-      * @brief  Reception  complete callback in non blocking mode
-      * @param  obj->hcan: pointer to a CAN_HandleTypeDef structure that contains
-      *         the configuration information for the specified CAN.
-      * @retval None
-      */
-    void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
-    {    
-        /* Add message we jsut received to the can_message_queue */
-        /* cheats and uses global pointer to the only can_t used for STM32 F0 */
-        message_enqueue(single_can_controller, hcan->pRxMsg);
-        
-        /* Call user callback */
-        irq_handler (can_irq_ids[0], IRQ_RX);
+
+/**
+  * @brief  Reception  complete callback in non blocking mode
+  * @param  hcan: pointer to a CAN_HandleTypeDef structure that contains
+  *         the configuration information for the specified CAN.
+  * @retval None
+  */
+void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
+{
+    // if(HAL_CAN_Receive_IT(hcan, CAN_FIFO0) == HAL_OK) {
+    //     if(rxCompleteCallback != NULL)
+    //         rxCompleteCallback();
+    // }
+    // else {
+    //     error_handler(error);
+    // }
+
+    // BUG: CAN race condition if HAL_CAN_Receive_IT() is used.
+    // See https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Java%2FBUG%20CAN%20race%20condition%20if%20HAL%5FCAN%5FReceive%5FIT%20is%20used
+    //
+    // Fixed by Mark Burton:
+    // ideally, we should be able to call HAL_CAN_Receive_IT() here to set up for another
+    // receive but the API is flawed because that function will fail if HAL_CAN_Transmit()
+    // had already locked the handle when the receive interrupt occurred - so we do what
+    // HAL_CAN_Receive_IT() would do
+
     
-        /*
-         * BUG: CAN race condition if HAL_CAN_Receive_IT() is used.
-         * See https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Java/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32Java%2FBUG%20CAN%20race%20condition%20if%20HAL%5FCAN%5FReceive%5FIT%20is%20used
-         *
-         * Fixed by Mark Burton:
-         * ideally, we should be able to call HAL_CAN_Receive_IT() here to set up for another
-         * receive but the API is flawed because that function will fail if HAL_CAN_Transmit()
-         * had already locked the handle when the receive interrupt occurred - so we do what
-         * HAL_CAN_Receive_IT() would do
-         */
-         
-        /* perform HAL_CAN_Receive_IT() fix */
-        if (hcan->State == HAL_CAN_STATE_BUSY_TX) {
-            hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
-        } else {
-            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);
-        }
-    
-        // Enable FIFO 0 message pending Interrupt
-        __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
-    
+    irq_handler (can_irq_ids[0], IRQ_RX);
+
+    if (hcan->State == HAL_CAN_STATE_BUSY_TX)
+        hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
+    else {
+        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);
     }
-#endif /* USE_RECEIVE_IT */
+
+    // Enable FIFO 0 message pending Interrupt
+    __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
+}