mbed library sources, include can_api for nucleo-f091rc

Dependents:   CanNucleoF0_example

Fork of mbed-src by mbed official

Committer:
ptpaterson
Date:
Thu Jan 07 05:49:05 2016 +0000
Revision:
645:13c87cbecd54
Parent:
642:069330c922be
corrected freeze on CAN_RECEIVE_IT

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ptpaterson 639:15f853e90e6b 1 /*
ptpaterson 639:15f853e90e6b 2 ******************************************************************************
ptpaterson 639:15f853e90e6b 3 * @file can_api.c
ptpaterson 639:15f853e90e6b 4 * @author Zoltan Hudak
ptpaterson 639:15f853e90e6b 5 * @version
ptpaterson 639:15f853e90e6b 6 * @date 04-August-2015
ptpaterson 639:15f853e90e6b 7 * @brief CAN api for NUCLEO-F103RB platform
ptpaterson 639:15f853e90e6b 8 ******************************************************************************
ptpaterson 639:15f853e90e6b 9 * @attention
ptpaterson 639:15f853e90e6b 10 *
ptpaterson 639:15f853e90e6b 11 * <h2><center>&copy; COPYRIGHT(c) 2015 Zoltan Hudak <hudakz@inbox.com>
ptpaterson 639:15f853e90e6b 12 *
ptpaterson 639:15f853e90e6b 13 * All rights reserved.
ptpaterson 639:15f853e90e6b 14
ptpaterson 639:15f853e90e6b 15 This program is free software: you can redistribute it and/or modify
ptpaterson 639:15f853e90e6b 16 it under the terms of the GNU General Public License as published by
ptpaterson 639:15f853e90e6b 17 the Free Software Foundation, either version 3 of the License, or
ptpaterson 639:15f853e90e6b 18 (at your option) any later version.
ptpaterson 639:15f853e90e6b 19
ptpaterson 639:15f853e90e6b 20 This program is distributed in the hope that it will be useful,
ptpaterson 639:15f853e90e6b 21 but WITHOUT ANY WARRANTY; without even the implied warranty of
ptpaterson 639:15f853e90e6b 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ptpaterson 639:15f853e90e6b 23 GNU General Public License for more details.
ptpaterson 639:15f853e90e6b 24
ptpaterson 639:15f853e90e6b 25 You should have received a copy of the GNU General Public License
ptpaterson 639:15f853e90e6b 26 along with this program. If not, see <http://www.gnu.org/licenses/>.
ptpaterson 639:15f853e90e6b 27 */
ptpaterson 639:15f853e90e6b 28
ptpaterson 639:15f853e90e6b 29 /* Some code reused from STM32CubeMX */
ptpaterson 639:15f853e90e6b 30 /******************************************************************************
ptpaterson 639:15f853e90e6b 31 *
ptpaterson 639:15f853e90e6b 32 * COPYRIGHT(c) 2015 STMicroelectronics
ptpaterson 639:15f853e90e6b 33 *
ptpaterson 639:15f853e90e6b 34 * Redistribution and use in source and binary forms, with or without modification,
ptpaterson 639:15f853e90e6b 35 * are permitted provided that the following conditions are met:
ptpaterson 639:15f853e90e6b 36 * 1. Redistributions of source code must retain the above copyright notice,
ptpaterson 639:15f853e90e6b 37 * this list of conditions and the following disclaimer.
ptpaterson 639:15f853e90e6b 38 * 2. Redistributions in binary form must reproduce the above copyright notice,
ptpaterson 639:15f853e90e6b 39 * this list of conditions and the following disclaimer in the documentation
ptpaterson 639:15f853e90e6b 40 * and/or other materials provided with the distribution.
ptpaterson 639:15f853e90e6b 41 * 3. Neither the name of STMicroelectronics nor the names of its contributors
ptpaterson 639:15f853e90e6b 42 * may be used to endorse or promote products derived from this software
ptpaterson 639:15f853e90e6b 43 * without specific prior written permission.
ptpaterson 639:15f853e90e6b 44 *
ptpaterson 639:15f853e90e6b 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ptpaterson 639:15f853e90e6b 46 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ptpaterson 639:15f853e90e6b 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ptpaterson 639:15f853e90e6b 48 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
ptpaterson 639:15f853e90e6b 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ptpaterson 639:15f853e90e6b 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
ptpaterson 639:15f853e90e6b 51 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
ptpaterson 639:15f853e90e6b 52 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ptpaterson 639:15f853e90e6b 53 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
ptpaterson 639:15f853e90e6b 54 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ptpaterson 639:15f853e90e6b 55 *
ptpaterson 639:15f853e90e6b 56 ******************************************************************************
ptpaterson 639:15f853e90e6b 57 */
ptpaterson 639:15f853e90e6b 58
ptpaterson 639:15f853e90e6b 59 /* also some code taken from other mbed can_api.c */
ptpaterson 639:15f853e90e6b 60
ptpaterson 639:15f853e90e6b 61 /* mbed Microcontroller Library
ptpaterson 639:15f853e90e6b 62 * Copyright (c) 2006-2013 ARM Limited
ptpaterson 639:15f853e90e6b 63 *
ptpaterson 639:15f853e90e6b 64 * Licensed under the Apache License, Version 2.0 (the "License");
ptpaterson 639:15f853e90e6b 65 * you may not use this file except in compliance with the License.
ptpaterson 639:15f853e90e6b 66 * You may obtain a copy of the License at
ptpaterson 639:15f853e90e6b 67 *
ptpaterson 639:15f853e90e6b 68 * http://www.apache.org/licenses/LICENSE-2.0
ptpaterson 639:15f853e90e6b 69 *
ptpaterson 639:15f853e90e6b 70 * Unless required by applicable law or agreed to in writing, software
ptpaterson 639:15f853e90e6b 71 * distributed under the License is distributed on an "AS IS" BASIS,
ptpaterson 639:15f853e90e6b 72 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ptpaterson 639:15f853e90e6b 73 * See the License for the specific language governing permissions and
ptpaterson 639:15f853e90e6b 74 * limitations under the License.
ptpaterson 639:15f853e90e6b 75 */
ptpaterson 639:15f853e90e6b 76
ptpaterson 639:15f853e90e6b 77 /* Modified by Paul Paterson */
ptpaterson 639:15f853e90e6b 78
ptpaterson 639:15f853e90e6b 79 #include "stm32f0xx_hal.h"
ptpaterson 639:15f853e90e6b 80 #include "can_api.h"
ptpaterson 639:15f853e90e6b 81 #include "can_helper.h"
ptpaterson 639:15f853e90e6b 82 #include "pinmap.h"
ptpaterson 640:7eb9b8c299cd 83 #include "string.h"
ptpaterson 639:15f853e90e6b 84
ptpaterson 639:15f853e90e6b 85 #include "mbed.h"
ptpaterson 639:15f853e90e6b 86
ptpaterson 641:89738b4aac53 87 #define CAN_NUM 1
ptpaterson 639:15f853e90e6b 88
ptpaterson 639:15f853e90e6b 89 /**
ptpaterson 641:89738b4aac53 90 * @brief indicate to use the interrupt method or polling method.
ptpaterson 641:89738b4aac53 91 * @note Having serious difficulty determining why interrupt
ptpaterson 641:89738b4aac53 92 * method will not work. Best I can tell so far is that it is
ptpaterson 641:89738b4aac53 93 * getting stuck in a loop inside the ISR and refusing to come
ptpaterson 641:89738b4aac53 94 * out. The blinking led is on a scheduled task, so the fact that
ptpaterson 641:89738b4aac53 95 * it freezes upon receiving a message (write is fine!) supports
ptpaterson 641:89738b4aac53 96 * my guess.
ptpaterson 639:15f853e90e6b 97 */
ptpaterson 645:13c87cbecd54 98
ptpaterson 641:89738b4aac53 99
ptpaterson 645:13c87cbecd54 100 /* holder for objects that need to be global */
ptpaterson 645:13c87cbecd54 101 CAN_HandleTypeDef hcan;
ptpaterson 641:89738b4aac53 102 static PinName pinRd;
ptpaterson 641:89738b4aac53 103 static PinName pinTd;
ptpaterson 639:15f853e90e6b 104
ptpaterson 639:15f853e90e6b 105 /**
ptpaterson 645:13c87cbecd54 106 * @note
ptpaterson 645:13c87cbecd54 107 * @param
ptpaterson 645:13c87cbecd54 108 * @retval none
ptpaterson 645:13c87cbecd54 109 */
ptpaterson 645:13c87cbecd54 110 void can_init (can_t *obj, PinName rd, PinName td)
ptpaterson 645:13c87cbecd54 111 {
ptpaterson 639:15f853e90e6b 112 // DEBUG
ptpaterson 639:15f853e90e6b 113 printf("api: can_init\r\n");
ptpaterson 645:13c87cbecd54 114
ptpaterson 645:13c87cbecd54 115 /* set global pin values for MSP functions */
ptpaterson 639:15f853e90e6b 116 pinRd = rd;
ptpaterson 639:15f853e90e6b 117 pinTd = td;
ptpaterson 639:15f853e90e6b 118
ptpaterson 645:13c87cbecd54 119 /* Set the peripheral pointer */
ptpaterson 645:13c87cbecd54 120 hcan.Instance = ((CAN_TypeDef*)CAN_BASE);
ptpaterson 639:15f853e90e6b 121
ptpaterson 645:13c87cbecd54 122 /* initialize the mail boxes */
ptpaterson 639:15f853e90e6b 123 static CanTxMsgTypeDef txMessage;
ptpaterson 639:15f853e90e6b 124 static CanRxMsgTypeDef rxMessage;
ptpaterson 645:13c87cbecd54 125 hcan.pTxMsg = &txMessage;
ptpaterson 645:13c87cbecd54 126 hcan.pRxMsg = &rxMessage;
ptpaterson 639:15f853e90e6b 127
ptpaterson 645:13c87cbecd54 128 /* Initialize the CAN peripheral */
ptpaterson 645:13c87cbecd54 129 hcan.Init.TTCM = DISABLE;
ptpaterson 645:13c87cbecd54 130 hcan.Init.ABOM = ENABLE;
ptpaterson 645:13c87cbecd54 131 hcan.Init.AWUM = DISABLE;
ptpaterson 645:13c87cbecd54 132 hcan.Init.NART = DISABLE;
ptpaterson 645:13c87cbecd54 133 hcan.Init.RFLM = DISABLE;
ptpaterson 645:13c87cbecd54 134 hcan.Init.TXFP = DISABLE;
ptpaterson 645:13c87cbecd54 135 hcan.Init.Mode = CAN_MODE_NORMAL;
ptpaterson 639:15f853e90e6b 136
ptpaterson 645:13c87cbecd54 137 // 125kbps bit rate (default)
ptpaterson 645:13c87cbecd54 138 // APB1 peripheral clock = 48000000Hz
ptpaterson 645:13c87cbecd54 139 hcan.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16
ptpaterson 645:13c87cbecd54 140 hcan.Init.SJW = CAN_SJW_1TQ;
ptpaterson 645:13c87cbecd54 141 hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
ptpaterson 645:13c87cbecd54 142 hcan.Init.BS2 = CAN_BS2_4TQ;
ptpaterson 639:15f853e90e6b 143
ptpaterson 645:13c87cbecd54 144 int status = HAL_CAN_Init (&hcan);
ptpaterson 639:15f853e90e6b 145 if (status != HAL_OK) {
ptpaterson 639:15f853e90e6b 146 printf("api: can_init: HAL_CAN_INIT issue\r\n");
ptpaterson 639:15f853e90e6b 147 }
ptpaterson 639:15f853e90e6b 148
ptpaterson 639:15f853e90e6b 149 /* minimum filter required to make this work */
ptpaterson 639:15f853e90e6b 150 can_filter (obj, 0, 0, CANAny, 0);
ptpaterson 639:15f853e90e6b 151
ptpaterson 639:15f853e90e6b 152 return;
ptpaterson 639:15f853e90e6b 153 }
ptpaterson 639:15f853e90e6b 154
ptpaterson 639:15f853e90e6b 155 /**
ptpaterson 639:15f853e90e6b 156 * @brief
ptpaterson 639:15f853e90e6b 157 * @note
ptpaterson 639:15f853e90e6b 158 * @param
ptpaterson 639:15f853e90e6b 159 * @retval
ptpaterson 639:15f853e90e6b 160 */
ptpaterson 639:15f853e90e6b 161 void
ptpaterson 639:15f853e90e6b 162 can_free (can_t *obj)
ptpaterson 639:15f853e90e6b 163 {
ptpaterson 645:13c87cbecd54 164 HAL_CAN_DeInit (&hcan);
ptpaterson 639:15f853e90e6b 165 }
ptpaterson 639:15f853e90e6b 166
ptpaterson 639:15f853e90e6b 167 /**
ptpaterson 639:15f853e90e6b 168 * @brief
ptpaterson 639:15f853e90e6b 169 * @note
ptpaterson 639:15f853e90e6b 170 * @param
ptpaterson 639:15f853e90e6b 171 * @retval
ptpaterson 639:15f853e90e6b 172 */
ptpaterson 645:13c87cbecd54 173 int can_frequency(can_t *obj, int hz)
ptpaterson 639:15f853e90e6b 174 {
ptpaterson 639:15f853e90e6b 175 HAL_NVIC_DisableIRQ(CEC_CAN_IRQn);
ptpaterson 639:15f853e90e6b 176
ptpaterson 645:13c87cbecd54 177 // APB1 peripheral clock = 48000000Hz
ptpaterson 639:15f853e90e6b 178 switch(hz) {
ptpaterson 639:15f853e90e6b 179 case 1000000:
ptpaterson 639:15f853e90e6b 180 // 1000kbps bit rate
ptpaterson 645:13c87cbecd54 181 hcan.Init.Prescaler = 4; // number of time quanta = 48000000/4/1000000 = 12
ptpaterson 645:13c87cbecd54 182 hcan.Init.SJW = CAN_SJW_1TQ;
ptpaterson 645:13c87cbecd54 183 hcan.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
ptpaterson 645:13c87cbecd54 184 hcan.Init.BS2 = CAN_BS2_3TQ;
ptpaterson 639:15f853e90e6b 185 break;
ptpaterson 639:15f853e90e6b 186
ptpaterson 639:15f853e90e6b 187 case 500000:
ptpaterson 639:15f853e90e6b 188 // 500kbps bit rate
ptpaterson 645:13c87cbecd54 189 hcan.Init.Prescaler = 8; // number of time quanta = 48000000/8/500000 = 12
ptpaterson 645:13c87cbecd54 190 hcan.Init.SJW = CAN_SJW_1TQ;
ptpaterson 645:13c87cbecd54 191 hcan.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
ptpaterson 645:13c87cbecd54 192 hcan.Init.BS2 = CAN_BS2_3TQ;
ptpaterson 639:15f853e90e6b 193 break;
ptpaterson 639:15f853e90e6b 194
ptpaterson 639:15f853e90e6b 195 case 250000:
ptpaterson 639:15f853e90e6b 196 // 250kbps
ptpaterson 645:13c87cbecd54 197 hcan.Init.Prescaler = 12; // number of time quanta = 48000000/12/250000 = 16
ptpaterson 645:13c87cbecd54 198 hcan.Init.SJW = CAN_SJW_1TQ;
ptpaterson 645:13c87cbecd54 199 hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
ptpaterson 645:13c87cbecd54 200 hcan.Init.BS2 = CAN_BS2_4TQ;
ptpaterson 639:15f853e90e6b 201 break;
ptpaterson 639:15f853e90e6b 202
ptpaterson 639:15f853e90e6b 203 case 125000:
ptpaterson 639:15f853e90e6b 204 // 125kbps
ptpaterson 645:13c87cbecd54 205 hcan.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16
ptpaterson 645:13c87cbecd54 206 hcan.Init.SJW = CAN_SJW_1TQ;
ptpaterson 645:13c87cbecd54 207 hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
ptpaterson 645:13c87cbecd54 208 hcan.Init.BS2 = CAN_BS2_4TQ;
ptpaterson 639:15f853e90e6b 209 break;
ptpaterson 639:15f853e90e6b 210
ptpaterson 639:15f853e90e6b 211 default:
ptpaterson 639:15f853e90e6b 212 // 125kbps (default)
ptpaterson 645:13c87cbecd54 213 hcan.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16
ptpaterson 645:13c87cbecd54 214 hcan.Init.SJW = CAN_SJW_1TQ;
ptpaterson 645:13c87cbecd54 215 hcan.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
ptpaterson 645:13c87cbecd54 216 hcan.Init.BS2 = CAN_BS2_4TQ;
ptpaterson 645:13c87cbecd54 217 break;
ptpaterson 639:15f853e90e6b 218 }
ptpaterson 645:13c87cbecd54 219
ptpaterson 645:13c87cbecd54 220 HAL_CAN_Init(&hcan);
ptpaterson 639:15f853e90e6b 221
ptpaterson 639:15f853e90e6b 222 /* HAL_CAN_INIT will call HAL_CAN_MspInit, which will init the interupts */
ptpaterson 639:15f853e90e6b 223
ptpaterson 639:15f853e90e6b 224 return 1;
ptpaterson 639:15f853e90e6b 225 }
ptpaterson 639:15f853e90e6b 226
ptpaterson 639:15f853e90e6b 227 /*
ptpaterson 639:15f853e90e6b 228 * these will get setup in can_irq_init()
ptpaterson 639:15f853e90e6b 229 * and used later in HAL_CAN_RxCpltCallback()
ptpaterson 639:15f853e90e6b 230 */
ptpaterson 639:15f853e90e6b 231
ptpaterson 645:13c87cbecd54 232 #define CAN_MESSAGE_QUEUE_SIZE 10
ptpaterson 639:15f853e90e6b 233
ptpaterson 639:15f853e90e6b 234
ptpaterson 645:13c87cbecd54 235 /**
ptpaterson 645:13c87cbecd54 236 * @brief Queue to hold several incomming messages while we wait for the user
ptpaterson 645:13c87cbecd54 237 * to call for them.
ptpaterson 645:13c87cbecd54 238 * @note This is only necessary now, because the STM32 HAL handles the can
ptpaterson 645:13c87cbecd54 239 * receive FIFO by writing to the CAN_HandleTypeDef and popping from the built
ptpaterson 645:13c87cbecd54 240 * in queue.
ptpaterson 645:13c87cbecd54 241 */
ptpaterson 645:13c87cbecd54 242 typedef struct {
ptpaterson 645:13c87cbecd54 243 int next;
ptpaterson 645:13c87cbecd54 244 unsigned int contain_mask;
ptpaterson 645:13c87cbecd54 245 CanRxMsgTypeDef queue[CAN_MESSAGE_QUEUE_SIZE];
ptpaterson 645:13c87cbecd54 246 } can_message_queue;
ptpaterson 645:13c87cbecd54 247
ptpaterson 645:13c87cbecd54 248 static can_message_queue message_queues[CAN_NUM];
ptpaterson 645:13c87cbecd54 249
ptpaterson 645:13c87cbecd54 250 /**
ptpaterson 645:13c87cbecd54 251 * @brief Adds one message to the queue
ptpaterson 645:13c87cbecd54 252 * @note sends indication of overflow if it happens but overwites anyway
ptpaterson 645:13c87cbecd54 253 */
ptpaterson 645:13c87cbecd54 254 static int message_enqueue(can_t *obj,
ptpaterson 645:13c87cbecd54 255 CanRxMsgTypeDef *msg)
ptpaterson 645:13c87cbecd54 256 {
ptpaterson 645:13c87cbecd54 257 int result = 1;
ptpaterson 645:13c87cbecd54 258
ptpaterson 645:13c87cbecd54 259 int next = message_queues[obj->index].next;
ptpaterson 645:13c87cbecd54 260 if (++next >= CAN_MESSAGE_QUEUE_SIZE)
ptpaterson 645:13c87cbecd54 261 next = 0;
ptpaterson 645:13c87cbecd54 262
ptpaterson 645:13c87cbecd54 263 if (message_queues[obj->index].contain_mask & (1 << next))
ptpaterson 645:13c87cbecd54 264 result = 0; /* overflow */
ptpaterson 645:13c87cbecd54 265
ptpaterson 645:13c87cbecd54 266 message_queues[obj->index].queue[next] = *msg;
ptpaterson 645:13c87cbecd54 267 message_queues[obj->index].next = next;
ptpaterson 645:13c87cbecd54 268 message_queues[obj->index].contain_mask |= next;
ptpaterson 645:13c87cbecd54 269
ptpaterson 645:13c87cbecd54 270 return result;
ptpaterson 645:13c87cbecd54 271 }
ptpaterson 645:13c87cbecd54 272
ptpaterson 645:13c87cbecd54 273 /**
ptpaterson 645:13c87cbecd54 274 * @brief Pops one message from the queue
ptpaterson 645:13c87cbecd54 275 * @note sends indication of overflow if it happens but overwites anyway
ptpaterson 645:13c87cbecd54 276 */
ptpaterson 645:13c87cbecd54 277 static int message_dequeue(can_t *obj,
ptpaterson 645:13c87cbecd54 278 CanRxMsgTypeDef *msg)
ptpaterson 645:13c87cbecd54 279 {
ptpaterson 645:13c87cbecd54 280 int result = 1;
ptpaterson 645:13c87cbecd54 281
ptpaterson 645:13c87cbecd54 282 int next = message_queues[obj->index].next;
ptpaterson 645:13c87cbecd54 283
ptpaterson 645:13c87cbecd54 284 if (message_queues[obj->index].contain_mask & (1 << next)) {
ptpaterson 645:13c87cbecd54 285
ptpaterson 645:13c87cbecd54 286 *msg = message_queues[obj->index].queue[next];
ptpaterson 645:13c87cbecd54 287 message_queues[obj->index].contain_mask &= ~next;
ptpaterson 645:13c87cbecd54 288
ptpaterson 645:13c87cbecd54 289 if (--next < 0)
ptpaterson 645:13c87cbecd54 290 next = CAN_MESSAGE_QUEUE_SIZE - 1;
ptpaterson 645:13c87cbecd54 291 message_queues[obj->index].next = next;
ptpaterson 645:13c87cbecd54 292
ptpaterson 645:13c87cbecd54 293 } else {
ptpaterson 645:13c87cbecd54 294 result = 0; /* no current message */
ptpaterson 645:13c87cbecd54 295 }
ptpaterson 645:13c87cbecd54 296
ptpaterson 645:13c87cbecd54 297 return result;
ptpaterson 645:13c87cbecd54 298 }
ptpaterson 645:13c87cbecd54 299
ptpaterson 645:13c87cbecd54 300 /** becomes a pointer to the member function Can::_irq_handler */
ptpaterson 645:13c87cbecd54 301 static can_irq_handler irq_handler;
ptpaterson 645:13c87cbecd54 302
ptpaterson 645:13c87cbecd54 303 /** id is really just a pointer to the Can object
ptpaterson 645:13c87cbecd54 304 * useful for uC's that have multiple CAN devices
ptpaterson 645:13c87cbecd54 305 */
ptpaterson 645:13c87cbecd54 306 static uint32_t can_irq_ids[CAN_NUM] = {0};
ptpaterson 645:13c87cbecd54 307
ptpaterson 645:13c87cbecd54 308
ptpaterson 639:15f853e90e6b 309
ptpaterson 639:15f853e90e6b 310 /**
ptpaterson 639:15f853e90e6b 311 * @brief
ptpaterson 639:15f853e90e6b 312 * @note
ptpaterson 639:15f853e90e6b 313 * @param
ptpaterson 639:15f853e90e6b 314 * @retval
ptpaterson 639:15f853e90e6b 315 */
ptpaterson 639:15f853e90e6b 316 void
ptpaterson 639:15f853e90e6b 317 can_irq_init (can_t *obj,
ptpaterson 639:15f853e90e6b 318 can_irq_handler handler,
ptpaterson 639:15f853e90e6b 319 uint32_t id)
ptpaterson 639:15f853e90e6b 320 {
ptpaterson 645:13c87cbecd54 321 // DEBUG
ptpaterson 645:13c87cbecd54 322 printf("api: can_irq_init\r\n");
ptpaterson 645:13c87cbecd54 323
ptpaterson 645:13c87cbecd54 324 irq_handler = handler;
ptpaterson 645:13c87cbecd54 325 can_irq_ids[obj->index] = id;
ptpaterson 645:13c87cbecd54 326
ptpaterson 645:13c87cbecd54 327 message_queues[obj->index].contain_mask = 0;
ptpaterson 645:13c87cbecd54 328 message_queues[obj->index].next = CAN_MESSAGE_QUEUE_SIZE - 1;
ptpaterson 645:13c87cbecd54 329
ptpaterson 645:13c87cbecd54 330 if (HAL_CAN_Receive_IT (&hcan, CAN_FIFO0) != HAL_OK) {
ptpaterson 645:13c87cbecd54 331 printf("api: can_irq_init: receive failed\r\n");
ptpaterson 645:13c87cbecd54 332 }
ptpaterson 641:89738b4aac53 333 }
ptpaterson 639:15f853e90e6b 334
ptpaterson 639:15f853e90e6b 335
ptpaterson 639:15f853e90e6b 336 /**
ptpaterson 639:15f853e90e6b 337 * @brief
ptpaterson 639:15f853e90e6b 338 * @note
ptpaterson 639:15f853e90e6b 339 * @param
ptpaterson 639:15f853e90e6b 340 * @retval
ptpaterson 639:15f853e90e6b 341 */
ptpaterson 639:15f853e90e6b 342 void
ptpaterson 639:15f853e90e6b 343 can_irq_free (can_t *obj)
ptpaterson 639:15f853e90e6b 344 {
ptpaterson 639:15f853e90e6b 345 // TODO: free any resources not called by HAL_CAN_DeInit() */
ptpaterson 639:15f853e90e6b 346 }
ptpaterson 639:15f853e90e6b 347
ptpaterson 639:15f853e90e6b 348 /**
ptpaterson 639:15f853e90e6b 349 * @brief
ptpaterson 639:15f853e90e6b 350 * @note
ptpaterson 639:15f853e90e6b 351 * @param
ptpaterson 639:15f853e90e6b 352 * @retval
ptpaterson 639:15f853e90e6b 353 */
ptpaterson 639:15f853e90e6b 354 void
ptpaterson 639:15f853e90e6b 355 can_irq_set (can_t *obj,
ptpaterson 639:15f853e90e6b 356 CanIrqType irq,
ptpaterson 639:15f853e90e6b 357 uint32_t enable)
ptpaterson 639:15f853e90e6b 358 {
ptpaterson 641:89738b4aac53 359 /* record that the user has attached a callback of type CanIrqType */
ptpaterson 641:89738b4aac53 360 /* perhaps switch from polling to interrupt if we were that awesome! */
ptpaterson 639:15f853e90e6b 361 }
ptpaterson 639:15f853e90e6b 362
ptpaterson 639:15f853e90e6b 363 /**
ptpaterson 639:15f853e90e6b 364 * @brief
ptpaterson 639:15f853e90e6b 365 * @note
ptpaterson 639:15f853e90e6b 366 * @param
ptpaterson 639:15f853e90e6b 367 * @retval
ptpaterson 639:15f853e90e6b 368 */
ptpaterson 639:15f853e90e6b 369 int
ptpaterson 639:15f853e90e6b 370 can_write (can_t *obj,
ptpaterson 639:15f853e90e6b 371 CAN_Message msg,
ptpaterson 639:15f853e90e6b 372 int cc)
ptpaterson 639:15f853e90e6b 373 {
ptpaterson 639:15f853e90e6b 374 // DEBUG
ptpaterson 639:15f853e90e6b 375 printf("api: can_write\r\n");
ptpaterson 645:13c87cbecd54 376
ptpaterson 639:15f853e90e6b 377 if (msg.format == CANStandard) {
ptpaterson 645:13c87cbecd54 378 hcan.pTxMsg->StdId = msg.id;
ptpaterson 645:13c87cbecd54 379 hcan.pTxMsg->ExtId = 0x00;
ptpaterson 639:15f853e90e6b 380 } else {
ptpaterson 645:13c87cbecd54 381 hcan.pTxMsg->StdId = 0x00;
ptpaterson 645:13c87cbecd54 382 hcan.pTxMsg->ExtId = msg.id;
ptpaterson 639:15f853e90e6b 383 }
ptpaterson 639:15f853e90e6b 384
ptpaterson 645:13c87cbecd54 385 hcan.pTxMsg->RTR = msg.type == CANData ? CAN_RTR_DATA : CAN_RTR_REMOTE;
ptpaterson 645:13c87cbecd54 386 hcan.pTxMsg->IDE = msg.format == CANStandard ? CAN_ID_STD : CAN_ID_EXT;
ptpaterson 645:13c87cbecd54 387 hcan.pTxMsg->DLC = msg.len;
ptpaterson 639:15f853e90e6b 388
ptpaterson 645:13c87cbecd54 389 memcpy(hcan.pTxMsg->Data, &(msg.data), msg.len);
ptpaterson 639:15f853e90e6b 390
ptpaterson 639:15f853e90e6b 391 int result = 1;
ptpaterson 645:13c87cbecd54 392 if (HAL_CAN_Transmit(&hcan, 5) != HAL_OK) {
ptpaterson 639:15f853e90e6b 393 result = 0;
ptpaterson 639:15f853e90e6b 394 }
ptpaterson 639:15f853e90e6b 395
ptpaterson 639:15f853e90e6b 396 return result;
ptpaterson 639:15f853e90e6b 397
ptpaterson 639:15f853e90e6b 398 }
ptpaterson 639:15f853e90e6b 399
ptpaterson 639:15f853e90e6b 400 /**
ptpaterson 639:15f853e90e6b 401 * @brief
ptpaterson 639:15f853e90e6b 402 * @note
ptpaterson 639:15f853e90e6b 403 * @param
ptpaterson 639:15f853e90e6b 404 * @retval
ptpaterson 639:15f853e90e6b 405 */
ptpaterson 639:15f853e90e6b 406 int
ptpaterson 639:15f853e90e6b 407 can_read (can_t *obj,
ptpaterson 639:15f853e90e6b 408 CAN_Message *msg,
ptpaterson 639:15f853e90e6b 409 int handle)
ptpaterson 639:15f853e90e6b 410 {
ptpaterson 645:13c87cbecd54 411
ptpaterson 640:7eb9b8c299cd 412 int result = 0;
ptpaterson 645:13c87cbecd54 413
ptpaterson 645:13c87cbecd54 414 CanRxMsgTypeDef popMessage;
ptpaterson 645:13c87cbecd54 415 if (message_dequeue (obj, &popMessage)) {
ptpaterson 645:13c87cbecd54 416
ptpaterson 645:13c87cbecd54 417 msg->id = popMessage.IDE == CAN_ID_STD ? popMessage.StdId : popMessage.ExtId;
ptpaterson 645:13c87cbecd54 418 msg->type = popMessage.RTR == CAN_RTR_DATA ? CANData : CANRemote;
ptpaterson 645:13c87cbecd54 419 msg->format = popMessage.IDE == CAN_ID_STD ? CANStandard : CANExtended;
ptpaterson 645:13c87cbecd54 420 msg->len = popMessage.DLC;
ptpaterson 645:13c87cbecd54 421
ptpaterson 645:13c87cbecd54 422 memcpy(msg->data, &(popMessage.Data), msg->len);
ptpaterson 645:13c87cbecd54 423
ptpaterson 645:13c87cbecd54 424 result = msg->len;
ptpaterson 645:13c87cbecd54 425 }
ptpaterson 645:13c87cbecd54 426
ptpaterson 639:15f853e90e6b 427 return result;
ptpaterson 639:15f853e90e6b 428 }
ptpaterson 639:15f853e90e6b 429
ptpaterson 639:15f853e90e6b 430 /**
ptpaterson 639:15f853e90e6b 431 * @brief
ptpaterson 639:15f853e90e6b 432 * @note
ptpaterson 639:15f853e90e6b 433 * @param
ptpaterson 639:15f853e90e6b 434 * @retval
ptpaterson 639:15f853e90e6b 435 */
ptpaterson 639:15f853e90e6b 436 int
ptpaterson 639:15f853e90e6b 437 can_mode (can_t *obj,
ptpaterson 639:15f853e90e6b 438 CanMode mode)
ptpaterson 639:15f853e90e6b 439 {
ptpaterson 639:15f853e90e6b 440 int success = 0;
ptpaterson 639:15f853e90e6b 441
ptpaterson 639:15f853e90e6b 442 switch(mode) {
ptpaterson 639:15f853e90e6b 443 case MODE_RESET:
ptpaterson 639:15f853e90e6b 444 success = HAL_ERROR;
ptpaterson 639:15f853e90e6b 445 break;
ptpaterson 639:15f853e90e6b 446
ptpaterson 639:15f853e90e6b 447 case MODE_NORMAL:
ptpaterson 645:13c87cbecd54 448 hcan.Init.Mode = CAN_MODE_NORMAL;
ptpaterson 639:15f853e90e6b 449 break;
ptpaterson 639:15f853e90e6b 450
ptpaterson 639:15f853e90e6b 451 case MODE_SILENT:
ptpaterson 645:13c87cbecd54 452 hcan.Init.Mode = CAN_MODE_SILENT;
ptpaterson 639:15f853e90e6b 453 break;
ptpaterson 639:15f853e90e6b 454
ptpaterson 639:15f853e90e6b 455 case MODE_TEST_GLOBAL:
ptpaterson 645:13c87cbecd54 456 hcan.Init.Mode = CAN_MODE_LOOPBACK;
ptpaterson 639:15f853e90e6b 457 break;
ptpaterson 639:15f853e90e6b 458
ptpaterson 639:15f853e90e6b 459 case MODE_TEST_LOCAL:
ptpaterson 645:13c87cbecd54 460 hcan.Init.Mode = CAN_MODE_LOOPBACK;
ptpaterson 639:15f853e90e6b 461 break;
ptpaterson 639:15f853e90e6b 462
ptpaterson 639:15f853e90e6b 463 case MODE_TEST_SILENT:
ptpaterson 645:13c87cbecd54 464 hcan.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
ptpaterson 639:15f853e90e6b 465 break;
ptpaterson 639:15f853e90e6b 466 }
ptpaterson 639:15f853e90e6b 467
ptpaterson 639:15f853e90e6b 468 if (success != HAL_ERROR) {
ptpaterson 645:13c87cbecd54 469 success = HAL_CAN_Init(&hcan);
ptpaterson 639:15f853e90e6b 470 }
ptpaterson 639:15f853e90e6b 471
ptpaterson 639:15f853e90e6b 472 return success;
ptpaterson 639:15f853e90e6b 473 }
ptpaterson 639:15f853e90e6b 474
ptpaterson 639:15f853e90e6b 475 /**
ptpaterson 639:15f853e90e6b 476 * @brief
ptpaterson 639:15f853e90e6b 477 * @note
ptpaterson 639:15f853e90e6b 478 * @param
ptpaterson 639:15f853e90e6b 479 * @retval
ptpaterson 639:15f853e90e6b 480 */
ptpaterson 639:15f853e90e6b 481 int
ptpaterson 639:15f853e90e6b 482 can_filter (can_t *obj,
ptpaterson 639:15f853e90e6b 483 uint32_t id,
ptpaterson 639:15f853e90e6b 484 uint32_t mask,
ptpaterson 639:15f853e90e6b 485 CANFormat format,
ptpaterson 639:15f853e90e6b 486 int32_t handle)
ptpaterson 639:15f853e90e6b 487 {
ptpaterson 639:15f853e90e6b 488 CAN_FilterConfTypeDef sFilterConfig;
ptpaterson 639:15f853e90e6b 489
ptpaterson 639:15f853e90e6b 490 sFilterConfig.FilterNumber = handle; // Specifies the filter number (must be a number between 0 and 13 at 32-bit filter scale)
ptpaterson 639:15f853e90e6b 491 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
ptpaterson 639:15f853e90e6b 492 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
ptpaterson 639:15f853e90e6b 493 sFilterConfig.FilterIdHigh = (((id) >> 16) & 0xFFFF);
ptpaterson 639:15f853e90e6b 494 sFilterConfig.FilterIdLow = ((id) & 0xFFFF);
ptpaterson 639:15f853e90e6b 495 sFilterConfig.FilterMaskIdHigh = (((mask) >> 16) & 0xFFFF);
ptpaterson 639:15f853e90e6b 496 sFilterConfig.FilterMaskIdLow = ((mask) & 0xFFFF);
ptpaterson 639:15f853e90e6b 497 sFilterConfig.FilterFIFOAssignment = 0;
ptpaterson 639:15f853e90e6b 498 sFilterConfig.FilterActivation = ENABLE;
ptpaterson 639:15f853e90e6b 499 sFilterConfig.BankNumber = 0; // Selects the start bank filter
ptpaterson 639:15f853e90e6b 500
ptpaterson 645:13c87cbecd54 501 return HAL_CAN_ConfigFilter(&hcan, &sFilterConfig);
ptpaterson 639:15f853e90e6b 502 }
ptpaterson 639:15f853e90e6b 503
ptpaterson 639:15f853e90e6b 504 /**
ptpaterson 639:15f853e90e6b 505 * @brief
ptpaterson 639:15f853e90e6b 506 * @note
ptpaterson 639:15f853e90e6b 507 * @param
ptpaterson 639:15f853e90e6b 508 * @retval
ptpaterson 639:15f853e90e6b 509 */
ptpaterson 639:15f853e90e6b 510 void
ptpaterson 639:15f853e90e6b 511 can_reset (can_t *obj)
ptpaterson 639:15f853e90e6b 512 {
ptpaterson 645:13c87cbecd54 513 __HAL_CAN_RESET_HANDLE_STATE(&hcan);
ptpaterson 639:15f853e90e6b 514 }
ptpaterson 639:15f853e90e6b 515
ptpaterson 639:15f853e90e6b 516 /**
ptpaterson 639:15f853e90e6b 517 * @brief
ptpaterson 639:15f853e90e6b 518 * @note
ptpaterson 639:15f853e90e6b 519 * @param
ptpaterson 639:15f853e90e6b 520 * @retval
ptpaterson 639:15f853e90e6b 521 */
ptpaterson 639:15f853e90e6b 522 unsigned char
ptpaterson 639:15f853e90e6b 523 can_rderror (can_t *obj)
ptpaterson 639:15f853e90e6b 524 {
ptpaterson 645:13c87cbecd54 525 return HAL_CAN_GetError(&hcan);
ptpaterson 639:15f853e90e6b 526 }
ptpaterson 639:15f853e90e6b 527
ptpaterson 639:15f853e90e6b 528 /**
ptpaterson 639:15f853e90e6b 529 * @brief
ptpaterson 639:15f853e90e6b 530 * @note
ptpaterson 639:15f853e90e6b 531 * @param
ptpaterson 639:15f853e90e6b 532 * @retval
ptpaterson 639:15f853e90e6b 533 */
ptpaterson 639:15f853e90e6b 534 unsigned char
ptpaterson 639:15f853e90e6b 535 can_tderror (can_t *obj)
ptpaterson 639:15f853e90e6b 536 {
ptpaterson 645:13c87cbecd54 537 return HAL_CAN_GetError(&hcan);
ptpaterson 639:15f853e90e6b 538 }
ptpaterson 639:15f853e90e6b 539
ptpaterson 639:15f853e90e6b 540 /**
ptpaterson 639:15f853e90e6b 541 * @brief
ptpaterson 639:15f853e90e6b 542 * @note
ptpaterson 639:15f853e90e6b 543 * @param
ptpaterson 639:15f853e90e6b 544 * @retval
ptpaterson 639:15f853e90e6b 545 */
ptpaterson 639:15f853e90e6b 546 void
ptpaterson 639:15f853e90e6b 547 can_monitor (can_t *obj,
ptpaterson 639:15f853e90e6b 548 int silent)
ptpaterson 639:15f853e90e6b 549 {
ptpaterson 639:15f853e90e6b 550 // TODO: implement
ptpaterson 639:15f853e90e6b 551 }
ptpaterson 639:15f853e90e6b 552
ptpaterson 639:15f853e90e6b 553 /*=============================================================================
ptpaterson 639:15f853e90e6b 554 * HAL_MSP and other functions
ptpaterson 639:15f853e90e6b 555 *=============================================================================
ptpaterson 639:15f853e90e6b 556 */
ptpaterson 645:13c87cbecd54 557
ptpaterson 639:15f853e90e6b 558 /**
ptpaterson 639:15f853e90e6b 559 * @brief CAN MSP Initialization
ptpaterson 639:15f853e90e6b 560 * @param hcan: CAN handle pointer
ptpaterson 639:15f853e90e6b 561 * @retval None
ptpaterson 639:15f853e90e6b 562 */
ptpaterson 645:13c87cbecd54 563 void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
ptpaterson 639:15f853e90e6b 564 {
ptpaterson 639:15f853e90e6b 565 GPIO_InitTypeDef GPIO_InitStruct;
ptpaterson 645:13c87cbecd54 566
ptpaterson 645:13c87cbecd54 567 if((pinRd == PA_11) && (pinTd == PA_12)) {
ptpaterson 645:13c87cbecd54 568
ptpaterson 645:13c87cbecd54 569 /* CAN1 Periph clock enable */
ptpaterson 645:13c87cbecd54 570 __CAN_CLK_ENABLE();
ptpaterson 639:15f853e90e6b 571
ptpaterson 645:13c87cbecd54 572 /* Enable GPIO clock */
ptpaterson 645:13c87cbecd54 573 __GPIOA_CLK_ENABLE();
ptpaterson 645:13c87cbecd54 574
ptpaterson 645:13c87cbecd54 575 /* CAN1 RX GPIO pin configuration */
ptpaterson 645:13c87cbecd54 576 GPIO_InitStruct.Pin = GPIO_PIN_11;
ptpaterson 645:13c87cbecd54 577 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
ptpaterson 645:13c87cbecd54 578 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
ptpaterson 645:13c87cbecd54 579 GPIO_InitStruct.Pull = GPIO_NOPULL;
ptpaterson 645:13c87cbecd54 580 GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
ptpaterson 645:13c87cbecd54 581 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
ptpaterson 639:15f853e90e6b 582
ptpaterson 645:13c87cbecd54 583 /* CAN1 TX GPIO pin configuration */
ptpaterson 645:13c87cbecd54 584 GPIO_InitStruct.Pin = GPIO_PIN_12;
ptpaterson 645:13c87cbecd54 585 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
ptpaterson 645:13c87cbecd54 586 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
ptpaterson 645:13c87cbecd54 587 GPIO_InitStruct.Pull = GPIO_NOPULL;
ptpaterson 645:13c87cbecd54 588 GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
ptpaterson 645:13c87cbecd54 589 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
ptpaterson 645:13c87cbecd54 590 } else if((pinRd == PB_8) && (pinTd == PB_9)) {
ptpaterson 645:13c87cbecd54 591 /* CAN1 Periph clock enable */
ptpaterson 645:13c87cbecd54 592 __CAN_CLK_ENABLE();
ptpaterson 639:15f853e90e6b 593
ptpaterson 645:13c87cbecd54 594 /* Enable GPIO clock */
ptpaterson 645:13c87cbecd54 595 __GPIOB_CLK_ENABLE();
ptpaterson 639:15f853e90e6b 596
ptpaterson 645:13c87cbecd54 597 /* CAN1 RX GPIO pin configuration */
ptpaterson 645:13c87cbecd54 598 GPIO_InitStruct.Pin = GPIO_PIN_8;
ptpaterson 645:13c87cbecd54 599 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
ptpaterson 645:13c87cbecd54 600 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
ptpaterson 645:13c87cbecd54 601 GPIO_InitStruct.Pull = GPIO_NOPULL;
ptpaterson 645:13c87cbecd54 602 GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
ptpaterson 645:13c87cbecd54 603 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
ptpaterson 639:15f853e90e6b 604
ptpaterson 645:13c87cbecd54 605 /* CAN1 TX GPIO pin configuration */
ptpaterson 645:13c87cbecd54 606 GPIO_InitStruct.Pin = GPIO_PIN_9;
ptpaterson 645:13c87cbecd54 607 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
ptpaterson 645:13c87cbecd54 608 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
ptpaterson 645:13c87cbecd54 609 GPIO_InitStruct.Pull = GPIO_NOPULL;
ptpaterson 645:13c87cbecd54 610 GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
ptpaterson 645:13c87cbecd54 611 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
ptpaterson 645:13c87cbecd54 612 } else
ptpaterson 645:13c87cbecd54 613 return;
ptpaterson 645:13c87cbecd54 614 /* NVIC configuration for CAN1 Reception complete interrupt */
ptpaterson 645:13c87cbecd54 615 HAL_NVIC_SetPriority(CEC_CAN_IRQn, 1, 0);
ptpaterson 645:13c87cbecd54 616 HAL_NVIC_EnableIRQ(CEC_CAN_IRQn);
ptpaterson 639:15f853e90e6b 617 }
ptpaterson 639:15f853e90e6b 618
ptpaterson 639:15f853e90e6b 619 /**
ptpaterson 639:15f853e90e6b 620 * @brief CAN MSP De-Initialization
ptpaterson 639:15f853e90e6b 621 * This function frees the hardware resources used:
ptpaterson 639:15f853e90e6b 622 * - Disable the Peripheral's clock
ptpaterson 639:15f853e90e6b 623 * - Revert GPIO to their default state
ptpaterson 639:15f853e90e6b 624 * @param hcan: CAN handle pointer
ptpaterson 639:15f853e90e6b 625 * @retval None
ptpaterson 639:15f853e90e6b 626 */
ptpaterson 645:13c87cbecd54 627 void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
ptpaterson 639:15f853e90e6b 628 {
ptpaterson 645:13c87cbecd54 629
ptpaterson 645:13c87cbecd54 630 /* Reset peripherals */
ptpaterson 639:15f853e90e6b 631
ptpaterson 645:13c87cbecd54 632 __CAN_FORCE_RESET();
ptpaterson 645:13c87cbecd54 633 __CAN_RELEASE_RESET();
ptpaterson 639:15f853e90e6b 634
ptpaterson 645:13c87cbecd54 635 /* Disable peripherals and GPIO Clocks */
ptpaterson 645:13c87cbecd54 636 if((pinRd == PA_11) && (pinTd == PA_12)) {
ptpaterson 645:13c87cbecd54 637 /* De-initialize the CAN1 RX GPIO pin */
ptpaterson 645:13c87cbecd54 638 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11);
ptpaterson 645:13c87cbecd54 639
ptpaterson 645:13c87cbecd54 640 /* De-initialize the CAN1 TX GPIO pin */
ptpaterson 645:13c87cbecd54 641 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12);
ptpaterson 645:13c87cbecd54 642 } else {
ptpaterson 645:13c87cbecd54 643
ptpaterson 645:13c87cbecd54 644 /* De-initialize the CAN1 RX GPIO pin */
ptpaterson 645:13c87cbecd54 645 HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8);
ptpaterson 645:13c87cbecd54 646
ptpaterson 645:13c87cbecd54 647 /* De-initialize the CAN1 TX GPIO pin */
ptpaterson 645:13c87cbecd54 648 HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
ptpaterson 639:15f853e90e6b 649 }
ptpaterson 639:15f853e90e6b 650
ptpaterson 645:13c87cbecd54 651
ptpaterson 645:13c87cbecd54 652 /* Disable the NVIC for CAN reception */
ptpaterson 645:13c87cbecd54 653 HAL_NVIC_DisableIRQ(CEC_CAN_IRQn);
ptpaterson 645:13c87cbecd54 654 }
ptpaterson 645:13c87cbecd54 655
ptpaterson 645:13c87cbecd54 656 /**
ptpaterson 645:13c87cbecd54 657 * @brief Handles CAN RX0 interrupt request.
ptpaterson 645:13c87cbecd54 658 * @param None
ptpaterson 645:13c87cbecd54 659 * @note STM32F0 uses different interrupts than F4
ptpaterson 645:13c87cbecd54 660 * @retval None
ptpaterson 645:13c87cbecd54 661 */
ptpaterson 645:13c87cbecd54 662 void CEC_CAN_IRQHandler(void)
ptpaterson 645:13c87cbecd54 663 {
ptpaterson 645:13c87cbecd54 664 HAL_CAN_IRQHandler(&hcan);
ptpaterson 639:15f853e90e6b 665 }
ptpaterson 639:15f853e90e6b 666
ptpaterson 641:89738b4aac53 667
ptpaterson 645:13c87cbecd54 668
ptpaterson 645:13c87cbecd54 669 /**
ptpaterson 645:13c87cbecd54 670 * @brief Reception complete callback in non blocking mode
ptpaterson 645:13c87cbecd54 671 * @param hcan: pointer to a CAN_HandleTypeDef structure that contains
ptpaterson 645:13c87cbecd54 672 * the configuration information for the specified CAN.
ptpaterson 645:13c87cbecd54 673 * @retval None
ptpaterson 645:13c87cbecd54 674 */
ptpaterson 645:13c87cbecd54 675 void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
ptpaterson 645:13c87cbecd54 676 {
ptpaterson 645:13c87cbecd54 677 // if(HAL_CAN_Receive_IT(hcan, CAN_FIFO0) == HAL_OK) {
ptpaterson 645:13c87cbecd54 678 // if(rxCompleteCallback != NULL)
ptpaterson 645:13c87cbecd54 679 // rxCompleteCallback();
ptpaterson 645:13c87cbecd54 680 // }
ptpaterson 645:13c87cbecd54 681 // else {
ptpaterson 645:13c87cbecd54 682 // error_handler(error);
ptpaterson 645:13c87cbecd54 683 // }
ptpaterson 645:13c87cbecd54 684
ptpaterson 645:13c87cbecd54 685 // BUG: CAN race condition if HAL_CAN_Receive_IT() is used.
ptpaterson 645:13c87cbecd54 686 // 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
ptpaterson 645:13c87cbecd54 687 //
ptpaterson 645:13c87cbecd54 688 // Fixed by Mark Burton:
ptpaterson 645:13c87cbecd54 689 // ideally, we should be able to call HAL_CAN_Receive_IT() here to set up for another
ptpaterson 645:13c87cbecd54 690 // receive but the API is flawed because that function will fail if HAL_CAN_Transmit()
ptpaterson 645:13c87cbecd54 691 // had already locked the handle when the receive interrupt occurred - so we do what
ptpaterson 645:13c87cbecd54 692 // HAL_CAN_Receive_IT() would do
ptpaterson 645:13c87cbecd54 693
ptpaterson 639:15f853e90e6b 694
ptpaterson 645:13c87cbecd54 695 irq_handler (can_irq_ids[0], IRQ_RX);
ptpaterson 645:13c87cbecd54 696
ptpaterson 645:13c87cbecd54 697 if (hcan->State == HAL_CAN_STATE_BUSY_TX)
ptpaterson 645:13c87cbecd54 698 hcan->State = HAL_CAN_STATE_BUSY_TX_RX;
ptpaterson 645:13c87cbecd54 699 else {
ptpaterson 645:13c87cbecd54 700 hcan->State = HAL_CAN_STATE_BUSY_RX;
ptpaterson 645:13c87cbecd54 701
ptpaterson 645:13c87cbecd54 702 /* Set CAN error code to none */
ptpaterson 645:13c87cbecd54 703 hcan->ErrorCode = HAL_CAN_ERROR_NONE;
ptpaterson 645:13c87cbecd54 704
ptpaterson 645:13c87cbecd54 705 /* Enable Error warning Interrupt */
ptpaterson 645:13c87cbecd54 706 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG);
ptpaterson 645:13c87cbecd54 707
ptpaterson 645:13c87cbecd54 708 /* Enable Error passive Interrupt */
ptpaterson 645:13c87cbecd54 709 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV);
ptpaterson 645:13c87cbecd54 710
ptpaterson 645:13c87cbecd54 711 /* Enable Bus-off Interrupt */
ptpaterson 645:13c87cbecd54 712 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF);
ptpaterson 645:13c87cbecd54 713
ptpaterson 645:13c87cbecd54 714 /* Enable Last error code Interrupt */
ptpaterson 645:13c87cbecd54 715 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC);
ptpaterson 645:13c87cbecd54 716
ptpaterson 645:13c87cbecd54 717 /* Enable Error Interrupt */
ptpaterson 645:13c87cbecd54 718 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR);
ptpaterson 639:15f853e90e6b 719 }
ptpaterson 645:13c87cbecd54 720
ptpaterson 645:13c87cbecd54 721 // Enable FIFO 0 message pending Interrupt
ptpaterson 645:13c87cbecd54 722 __HAL_CAN_ENABLE_IT(hcan, CAN_IT_FMP0);
ptpaterson 645:13c87cbecd54 723 }