Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: CanNucleoF0_example
Fork of mbed-src by
Revision 645:13c87cbecd54, committed 2016-01-07
- 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 |
--- 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);
+}
