mbed library sources, include can_api for nucleo-f091rc
Dependents: CanNucleoF0_example
Fork of mbed-src by
targets/hal/TARGET_STM/TARGET_STM32F0/can_api.cpp@645:13c87cbecd54, 2016-01-07 (annotated)
- 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?
| User | Revision | Line number | New 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>© 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 | } |
