pub

Fork of CANnucleo by Zoltan Hudak

Committer:
hudakz
Date:
Sun Dec 25 14:03:41 2016 +0000
Revision:
26:173eea49222f
Parent:
24:c5d348e65e24
Child:
27:321a5b290148
CAN speed corrected for NUCLEO-F303K8.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:e29bc8e0dddd 1 /*
hudakz 5:b53e5ee15315 2 ******************************************************************************
hudakz 5:b53e5ee15315 3 * @file can_api.c
hudakz 5:b53e5ee15315 4 * @author Zoltan Hudak
hudakz 5:b53e5ee15315 5 * @version
hudakz 5:b53e5ee15315 6 * @date 04-August-2015
hudakz 5:b53e5ee15315 7 * @brief CAN api for NUCLEO-F103RB platform
hudakz 5:b53e5ee15315 8 ******************************************************************************
hudakz 5:b53e5ee15315 9 * @attention
hudakz 5:b53e5ee15315 10 *
hudakz 5:b53e5ee15315 11 * <h2><center>&copy; COPYRIGHT(c) 2015 Zoltan Hudak <hudakz@inbox.com>
hudakz 5:b53e5ee15315 12 *
hudakz 5:b53e5ee15315 13 * All rights reserved.
hudakz 0:e29bc8e0dddd 14
hudakz 0:e29bc8e0dddd 15 This program is free software: you can redistribute it and/or modify
hudakz 0:e29bc8e0dddd 16 it under the terms of the GNU General Public License as published by
hudakz 0:e29bc8e0dddd 17 the Free Software Foundation, either version 3 of the License, or
hudakz 0:e29bc8e0dddd 18 (at your option) any later version.
hudakz 0:e29bc8e0dddd 19
hudakz 0:e29bc8e0dddd 20 This program is distributed in the hope that it will be useful,
hudakz 0:e29bc8e0dddd 21 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 0:e29bc8e0dddd 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 0:e29bc8e0dddd 23 GNU General Public License for more details.
hudakz 0:e29bc8e0dddd 24
hudakz 0:e29bc8e0dddd 25 You should have received a copy of the GNU General Public License
hudakz 0:e29bc8e0dddd 26 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 0:e29bc8e0dddd 27 */
hudakz 24:c5d348e65e24 28 #include "cannucleo_api.h"
hudakz 0:e29bc8e0dddd 29 #include "can_helper.h"
hudakz 0:e29bc8e0dddd 30 #include "pinmap.h"
hudakz 0:e29bc8e0dddd 31
hudakz 20:bcd8161f8f6c 32 extern void (*rxCompleteCallback)(void);
hudakz 20:bcd8161f8f6c 33 extern CAN_HandleTypeDef _canHandle;
hudakz 20:bcd8161f8f6c 34
hudakz 20:bcd8161f8f6c 35 static uint32_t irq_id = 0;
hudakz 20:bcd8161f8f6c 36 static can_irq_handler irq_handler = 0;
hudakz 0:e29bc8e0dddd 37
hudakz 0:e29bc8e0dddd 38 /**
hudakz 0:e29bc8e0dddd 39 * @brief
hudakz 0:e29bc8e0dddd 40 * @note
hudakz 0:e29bc8e0dddd 41 * @param
hudakz 0:e29bc8e0dddd 42 * @retval
hudakz 0:e29bc8e0dddd 43 */
hudakz 20:bcd8161f8f6c 44 void can_init(PinName rd, PinName td, FunctionalState abom) {
hudakz 20:bcd8161f8f6c 45 initCAN(rd, td, abom);
hudakz 20:bcd8161f8f6c 46 can_filter(0, 0, CANAny, 0);
hudakz 0:e29bc8e0dddd 47 }
hudakz 0:e29bc8e0dddd 48
hudakz 0:e29bc8e0dddd 49 /**
hudakz 0:e29bc8e0dddd 50 * @brief
hudakz 0:e29bc8e0dddd 51 * @note
hudakz 0:e29bc8e0dddd 52 * @param
hudakz 0:e29bc8e0dddd 53 * @retval
hudakz 0:e29bc8e0dddd 54 */
hudakz 20:bcd8161f8f6c 55 void can_free(void) {
hudakz 15:5123ead7b002 56 HAL_CAN_MspDeInit(&_canHandle);
hudakz 0:e29bc8e0dddd 57 }
hudakz 0:e29bc8e0dddd 58
hudakz 0:e29bc8e0dddd 59 /**
hudakz 0:e29bc8e0dddd 60 * @brief
hudakz 0:e29bc8e0dddd 61 * @note
hudakz 0:e29bc8e0dddd 62 * @param
hudakz 0:e29bc8e0dddd 63 * @retval
hudakz 0:e29bc8e0dddd 64 */
hudakz 20:bcd8161f8f6c 65 int can_frequency(int hz) {
hudakz 15:5123ead7b002 66 HAL_NVIC_DisableIRQ(CAN_IRQ);
hudakz 16:f4c8f45bded9 67
hudakz 16:f4c8f45bded9 68 #if defined(TARGET_NUCLEO_F072RB) || \
hudakz 16:f4c8f45bded9 69 defined(TARGET_NUCLEO_F091RC)
hudakz 16:f4c8f45bded9 70
hudakz 16:f4c8f45bded9 71 // APB1 peripheral clock = 48000000Hz
hudakz 16:f4c8f45bded9 72
hudakz 16:f4c8f45bded9 73 switch(hz) {
hudakz 16:f4c8f45bded9 74 case 1000000:
hudakz 16:f4c8f45bded9 75 // 1000kbps bit rate
hudakz 16:f4c8f45bded9 76 _canHandle.Init.Prescaler = 4; // number of time quanta = 48000000/4/1000000 = 12
hudakz 16:f4c8f45bded9 77 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 78 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 16:f4c8f45bded9 79 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 16:f4c8f45bded9 80 break;
hudakz 16:f4c8f45bded9 81
hudakz 16:f4c8f45bded9 82 case 500000:
hudakz 16:f4c8f45bded9 83 // 500kbps bit rate
hudakz 16:f4c8f45bded9 84 _canHandle.Init.Prescaler = 8; // number of time quanta = 48000000/8/500000 = 12
hudakz 16:f4c8f45bded9 85 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 86 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 16:f4c8f45bded9 87 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 16:f4c8f45bded9 88 break;
hudakz 16:f4c8f45bded9 89
hudakz 16:f4c8f45bded9 90 case 250000:
hudakz 16:f4c8f45bded9 91 // 250kbps
hudakz 16:f4c8f45bded9 92 _canHandle.Init.Prescaler = 12; // number of time quanta = 48000000/12/250000 = 16
hudakz 16:f4c8f45bded9 93 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 94 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 16:f4c8f45bded9 95 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 16:f4c8f45bded9 96 break;
hudakz 16:f4c8f45bded9 97
hudakz 16:f4c8f45bded9 98 case 125000:
hudakz 16:f4c8f45bded9 99 // 125kbps
hudakz 16:f4c8f45bded9 100 _canHandle.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16
hudakz 16:f4c8f45bded9 101 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 102 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 16:f4c8f45bded9 103 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 16:f4c8f45bded9 104 break;
hudakz 16:f4c8f45bded9 105
hudakz 16:f4c8f45bded9 106 default:
hudakz 16:f4c8f45bded9 107 // 125kbps (default)
hudakz 16:f4c8f45bded9 108 _canHandle.Init.Prescaler = 24; // number of time quanta = 48000000/24/125000 = 16
hudakz 16:f4c8f45bded9 109 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 110 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 16:f4c8f45bded9 111 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 16:f4c8f45bded9 112 }
hudakz 0:e29bc8e0dddd 113
hudakz 16:f4c8f45bded9 114 #elif defined(TARGET_NUCLEO_F103RB) || \
hudakz 16:f4c8f45bded9 115 defined(TARGET_NUCLEO_F303RE) || \
hudakz 16:f4c8f45bded9 116 defined(TARGET_NUCLEO_F303K8) || \
hudakz 16:f4c8f45bded9 117 defined(TARGET_NUCLEO_F334R8) || \
hudakz 16:f4c8f45bded9 118 defined(TARGET_DISCO_F334C8)
hudakz 16:f4c8f45bded9 119
hudakz 5:b53e5ee15315 120 // APB1 peripheral clock = 36000000Hz
hudakz 0:e29bc8e0dddd 121
hudakz 0:e29bc8e0dddd 122 switch(hz) {
hudakz 0:e29bc8e0dddd 123 case 1000000:
hudakz 0:e29bc8e0dddd 124 // 1000kbps bit rate
hudakz 0:e29bc8e0dddd 125 _canHandle.Init.Prescaler = 3; // number of time quanta = 36000000/3/1000000 = 12
hudakz 0:e29bc8e0dddd 126 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 127 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 0:e29bc8e0dddd 128 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 0:e29bc8e0dddd 129 break;
hudakz 0:e29bc8e0dddd 130
hudakz 0:e29bc8e0dddd 131 case 500000:
hudakz 0:e29bc8e0dddd 132 // 500kbps bit rate
hudakz 0:e29bc8e0dddd 133 _canHandle.Init.Prescaler = 6; // number of time quanta = 36000000/6/500000 = 12
hudakz 0:e29bc8e0dddd 134 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 135 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 0:e29bc8e0dddd 136 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 0:e29bc8e0dddd 137 break;
hudakz 0:e29bc8e0dddd 138
hudakz 0:e29bc8e0dddd 139 case 250000:
hudakz 0:e29bc8e0dddd 140 // 250kbps
hudakz 0:e29bc8e0dddd 141 _canHandle.Init.Prescaler = 9; // number of time quanta = 36000000/9/250000 = 16
hudakz 0:e29bc8e0dddd 142 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 143 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 0:e29bc8e0dddd 144 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 0:e29bc8e0dddd 145 break;
hudakz 0:e29bc8e0dddd 146
hudakz 0:e29bc8e0dddd 147 case 125000:
hudakz 0:e29bc8e0dddd 148 // 125kbps
hudakz 0:e29bc8e0dddd 149 _canHandle.Init.Prescaler = 18; // number of time quanta = 36000000/18/125000 = 16
hudakz 0:e29bc8e0dddd 150 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 0:e29bc8e0dddd 151 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 0:e29bc8e0dddd 152 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 0:e29bc8e0dddd 153 break;
hudakz 0:e29bc8e0dddd 154
hudakz 0:e29bc8e0dddd 155 default:
hudakz 0:e29bc8e0dddd 156 // 125kbps (default)
hudakz 5:b53e5ee15315 157 #if DEBUG
hudakz 0:e29bc8e0dddd 158 printf("Unknown frequency specified!\r\n");
hudakz 0:e29bc8e0dddd 159 printf("Using default 125kbps\r\n");
hudakz 5:b53e5ee15315 160 #endif
hudakz 17:1fd35431ee8e 161 _canHandle.Init.Prescaler = 18; // number of time quanta = 36000000/18/125000 = 16
hudakz 16:f4c8f45bded9 162 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 17:1fd35431ee8e 163 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 16:f4c8f45bded9 164 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 16:f4c8f45bded9 165 }
hudakz 16:f4c8f45bded9 166
hudakz 26:173eea49222f 167 #elif defined(TARGET_NUCLEO_F303K8)
hudakz 26:173eea49222f 168
hudakz 26:173eea49222f 169 // APB1 peripheral clock = 32000000Hz
hudakz 26:173eea49222f 170
hudakz 26:173eea49222f 171 switch(hz) {
hudakz 26:173eea49222f 172 case 1000000:
hudakz 26:173eea49222f 173 // 1000kbps bit rate
hudakz 26:173eea49222f 174 _canHandle.Init.Prescaler = 2; // number of time quanta = 32000000/2/1000000 = 16
hudakz 26:173eea49222f 175 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 26:173eea49222f 176 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 26:173eea49222f 177 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 26:173eea49222f 178 break;
hudakz 26:173eea49222f 179
hudakz 26:173eea49222f 180 case 500000:
hudakz 26:173eea49222f 181 // 500kbps bit rate
hudakz 26:173eea49222f 182 _canHandle.Init.Prescaler = 4; // number of time quanta = 32000000/4/500000 = 16
hudakz 26:173eea49222f 183 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 26:173eea49222f 184 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 26:173eea49222f 185 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 26:173eea49222f 186 break;
hudakz 26:173eea49222f 187
hudakz 26:173eea49222f 188 case 250000:
hudakz 26:173eea49222f 189 // 250kbps
hudakz 26:173eea49222f 190 _canHandle.Init.Prescaler = 8; // number of time quanta = 32000000/8/250000 = 16
hudakz 26:173eea49222f 191 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 26:173eea49222f 192 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 26:173eea49222f 193 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 26:173eea49222f 194 break;
hudakz 26:173eea49222f 195
hudakz 26:173eea49222f 196 case 125000:
hudakz 26:173eea49222f 197 // 125kbps
hudakz 26:173eea49222f 198 _canHandle.Init.Prescaler = 16; // number of time quanta = 32000000/16/125000 = 16
hudakz 26:173eea49222f 199 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 26:173eea49222f 200 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 26:173eea49222f 201 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 26:173eea49222f 202 break;
hudakz 26:173eea49222f 203
hudakz 26:173eea49222f 204 default:
hudakz 26:173eea49222f 205 // 125kbps (default)
hudakz 26:173eea49222f 206 #if DEBUG
hudakz 26:173eea49222f 207 printf("Unknown frequency specified!\r\n");
hudakz 26:173eea49222f 208 printf("Using default 125kbps\r\n");
hudakz 26:173eea49222f 209 #endif
hudakz 26:173eea49222f 210 _canHandle.Init.Prescaler = 16; // number of time quanta = 32000000/16/125000 = 16
hudakz 26:173eea49222f 211 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 26:173eea49222f 212 _canHandle.Init.BS1 = CAN_BS1_11TQ; // sample point at: (1 + 11) / 16 * 100 = 75%
hudakz 26:173eea49222f 213 _canHandle.Init.BS2 = CAN_BS2_4TQ;
hudakz 26:173eea49222f 214 }
hudakz 26:173eea49222f 215
hudakz 16:f4c8f45bded9 216 #elif defined(TARGET_NUCLEO_F446RE)
hudakz 16:f4c8f45bded9 217
hudakz 16:f4c8f45bded9 218 // APB1 peripheral clock = 45000000Hz
hudakz 16:f4c8f45bded9 219
hudakz 16:f4c8f45bded9 220 switch(hz) {
hudakz 16:f4c8f45bded9 221 case 1000000:
hudakz 16:f4c8f45bded9 222 // 1000kbps bit rate
hudakz 16:f4c8f45bded9 223 _canHandle.Init.Prescaler = 5; // number of time quanta = 45000000/5/1000000 = 9
hudakz 16:f4c8f45bded9 224 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 225 _canHandle.Init.BS1 = CAN_BS1_6TQ; // sample point at: (1 + 6) / 9 * 100 = 77.78%
hudakz 16:f4c8f45bded9 226 _canHandle.Init.BS2 = CAN_BS2_2TQ;
hudakz 16:f4c8f45bded9 227 break;
hudakz 16:f4c8f45bded9 228
hudakz 16:f4c8f45bded9 229 case 500000:
hudakz 16:f4c8f45bded9 230 // 500kbps bit rate
hudakz 16:f4c8f45bded9 231 _canHandle.Init.Prescaler = 10; // number of time quanta = 45000000/10/500000 = 9
hudakz 16:f4c8f45bded9 232 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 233 _canHandle.Init.BS1 = CAN_BS1_6TQ; // sample point at: (1 + 6) / 9 * 100 = 77.78%
hudakz 16:f4c8f45bded9 234 _canHandle.Init.BS2 = CAN_BS2_2TQ;
hudakz 16:f4c8f45bded9 235 break;
hudakz 16:f4c8f45bded9 236
hudakz 16:f4c8f45bded9 237 case 250000:
hudakz 16:f4c8f45bded9 238 // 250kbps
hudakz 16:f4c8f45bded9 239 _canHandle.Init.Prescaler = 15; // number of time quanta = 45000000/15/250000 = 12
hudakz 16:f4c8f45bded9 240 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 241 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 16:f4c8f45bded9 242 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 16:f4c8f45bded9 243 break;
hudakz 16:f4c8f45bded9 244
hudakz 16:f4c8f45bded9 245 case 125000:
hudakz 16:f4c8f45bded9 246 // 125kbps
hudakz 16:f4c8f45bded9 247 _canHandle.Init.Prescaler = 30; // number of time quanta = 45000000/30/125000 = 12
hudakz 16:f4c8f45bded9 248 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 16:f4c8f45bded9 249 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 16:f4c8f45bded9 250 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 16:f4c8f45bded9 251 break;
hudakz 16:f4c8f45bded9 252
hudakz 16:f4c8f45bded9 253 default:
hudakz 16:f4c8f45bded9 254 // 125kbps (default)
hudakz 16:f4c8f45bded9 255 #if DEBUG
hudakz 16:f4c8f45bded9 256 printf("Unknown frequency specified!\r\n");
hudakz 16:f4c8f45bded9 257 printf("Using default 125kbps\r\n");
hudakz 16:f4c8f45bded9 258 #endif
hudakz 17:1fd35431ee8e 259 _canHandle.Init.Prescaler = 30; // number of time quanta = 45000000/30/125000 = 12
hudakz 0:e29bc8e0dddd 260 _canHandle.Init.SJW = CAN_SJW_1TQ;
hudakz 17:1fd35431ee8e 261 _canHandle.Init.BS1 = CAN_BS1_8TQ; // sample point at: (1 + 8) / 12 * 100 = 75%
hudakz 17:1fd35431ee8e 262 _canHandle.Init.BS2 = CAN_BS2_3TQ;
hudakz 0:e29bc8e0dddd 263 }
hudakz 16:f4c8f45bded9 264
hudakz 16:f4c8f45bded9 265 #endif
hudakz 0:e29bc8e0dddd 266
hudakz 0:e29bc8e0dddd 267 HAL_CAN_Init(&_canHandle);
hudakz 15:5123ead7b002 268 HAL_NVIC_EnableIRQ(CAN_IRQ);
hudakz 11:439f3a34c42e 269
hudakz 5:b53e5ee15315 270 return 1;
hudakz 0:e29bc8e0dddd 271 }
hudakz 0:e29bc8e0dddd 272
hudakz 0:e29bc8e0dddd 273 /**
hudakz 0:e29bc8e0dddd 274 * @brief
hudakz 0:e29bc8e0dddd 275 * @note
hudakz 0:e29bc8e0dddd 276 * @param
hudakz 0:e29bc8e0dddd 277 * @retval
hudakz 0:e29bc8e0dddd 278 */
hudakz 20:bcd8161f8f6c 279 void can_callback(void) {
hudakz 20:bcd8161f8f6c 280 irq_handler(irq_id, IRQ_RX);
hudakz 20:bcd8161f8f6c 281 }
hudakz 20:bcd8161f8f6c 282
hudakz 20:bcd8161f8f6c 283 /**
hudakz 20:bcd8161f8f6c 284 * @brief
hudakz 20:bcd8161f8f6c 285 * @note
hudakz 20:bcd8161f8f6c 286 * @param
hudakz 20:bcd8161f8f6c 287 * @retval
hudakz 20:bcd8161f8f6c 288 */
hudakz 20:bcd8161f8f6c 289 void can_irq_init(uint32_t id, can_irq_handler handler) {
hudakz 20:bcd8161f8f6c 290 irq_id = id;
hudakz 20:bcd8161f8f6c 291 irq_handler = handler;
hudakz 20:bcd8161f8f6c 292 rxCompleteCallback = can_callback;
hudakz 20:bcd8161f8f6c 293
hudakz 0:e29bc8e0dddd 294 if(HAL_CAN_Receive_IT(&_canHandle, CAN_FIFO0) != HAL_OK) {
hudakz 5:b53e5ee15315 295 #ifdef DEBUG
hudakz 0:e29bc8e0dddd 296 printf("CAN reception initialization error\r\n");
hudakz 5:b53e5ee15315 297 #endif
hudakz 0:e29bc8e0dddd 298 }
hudakz 0:e29bc8e0dddd 299 }
hudakz 0:e29bc8e0dddd 300
hudakz 0:e29bc8e0dddd 301 /**
hudakz 0:e29bc8e0dddd 302 * @brief
hudakz 0:e29bc8e0dddd 303 * @note
hudakz 0:e29bc8e0dddd 304 * @param
hudakz 0:e29bc8e0dddd 305 * @retval
hudakz 0:e29bc8e0dddd 306 */
hudakz 20:bcd8161f8f6c 307 void can_irq_free(void) {
hudakz 11:439f3a34c42e 308 rxCompleteCallback = 0;
hudakz 20:bcd8161f8f6c 309 }
hudakz 0:e29bc8e0dddd 310
hudakz 0:e29bc8e0dddd 311 /**
hudakz 0:e29bc8e0dddd 312 * @brief
hudakz 0:e29bc8e0dddd 313 * @note
hudakz 0:e29bc8e0dddd 314 * @param
hudakz 0:e29bc8e0dddd 315 * @retval
hudakz 0:e29bc8e0dddd 316 */
hudakz 20:bcd8161f8f6c 317 int can_write(CAN_Message msg, int cc) {
hudakz 0:e29bc8e0dddd 318 int i = 0;
hudakz 0:e29bc8e0dddd 319
hudakz 0:e29bc8e0dddd 320 if(msg.format == CANStandard) {
hudakz 0:e29bc8e0dddd 321 _canHandle.pTxMsg->StdId = msg.id;
hudakz 0:e29bc8e0dddd 322 _canHandle.pTxMsg->ExtId = 0x00;
hudakz 0:e29bc8e0dddd 323 }
hudakz 0:e29bc8e0dddd 324 else {
hudakz 0:e29bc8e0dddd 325 _canHandle.pTxMsg->StdId = 0x00;
hudakz 0:e29bc8e0dddd 326 _canHandle.pTxMsg->ExtId = msg.id;
hudakz 0:e29bc8e0dddd 327 }
hudakz 0:e29bc8e0dddd 328
hudakz 0:e29bc8e0dddd 329 _canHandle.pTxMsg->RTR = msg.type == CANData ? CAN_RTR_DATA : CAN_RTR_REMOTE;
hudakz 0:e29bc8e0dddd 330 _canHandle.pTxMsg->IDE = msg.format == CANStandard ? CAN_ID_STD : CAN_ID_EXT;
hudakz 0:e29bc8e0dddd 331 _canHandle.pTxMsg->DLC = msg.len;
hudakz 0:e29bc8e0dddd 332
hudakz 0:e29bc8e0dddd 333 for(i = 0; i < msg.len; i++)
hudakz 0:e29bc8e0dddd 334 _canHandle.pTxMsg->Data[i] = msg.data[i];
hudakz 0:e29bc8e0dddd 335
hudakz 0:e29bc8e0dddd 336 if(HAL_CAN_Transmit(&_canHandle, 10) != HAL_OK) {
hudakz 5:b53e5ee15315 337 #ifdef DEBUG
hudakz 0:e29bc8e0dddd 338 printf("Transmission error\r\n");
hudakz 5:b53e5ee15315 339 #endif
hudakz 5:b53e5ee15315 340 return 0;
hudakz 0:e29bc8e0dddd 341 }
hudakz 5:b53e5ee15315 342 else
hudakz 5:b53e5ee15315 343 return 1;
hudakz 0:e29bc8e0dddd 344 }
hudakz 0:e29bc8e0dddd 345
hudakz 0:e29bc8e0dddd 346 /**
hudakz 0:e29bc8e0dddd 347 * @brief
hudakz 0:e29bc8e0dddd 348 * @note
hudakz 0:e29bc8e0dddd 349 * @param
hudakz 0:e29bc8e0dddd 350 * @retval
hudakz 0:e29bc8e0dddd 351 */
hudakz 20:bcd8161f8f6c 352 int can_read(CAN_Message* msg, int handle) {
hudakz 10:227a455d0f9f 353 int i;
hudakz 0:e29bc8e0dddd 354 msg->id = _canHandle.pRxMsg->IDE == CAN_ID_STD ? _canHandle.pRxMsg->StdId : _canHandle.pRxMsg->ExtId;
hudakz 0:e29bc8e0dddd 355 msg->type = _canHandle.pRxMsg->RTR == CAN_RTR_DATA ? CANData : CANRemote;
hudakz 0:e29bc8e0dddd 356 msg->format = _canHandle.pRxMsg->IDE == CAN_ID_STD ? CANStandard : CANExtended;
hudakz 0:e29bc8e0dddd 357 msg->len = _canHandle.pRxMsg->DLC;
hudakz 10:227a455d0f9f 358 for(i = 0; i < msg->len; i++)
hudakz 0:e29bc8e0dddd 359 msg->data[i] = _canHandle.pRxMsg->Data[i];
hudakz 5:b53e5ee15315 360
hudakz 5:b53e5ee15315 361 return msg->len;
hudakz 0:e29bc8e0dddd 362 }
hudakz 0:e29bc8e0dddd 363
hudakz 0:e29bc8e0dddd 364 /**
hudakz 0:e29bc8e0dddd 365 * @brief
hudakz 0:e29bc8e0dddd 366 * @note
hudakz 0:e29bc8e0dddd 367 * @param
hudakz 0:e29bc8e0dddd 368 * @retval
hudakz 0:e29bc8e0dddd 369 */
hudakz 20:bcd8161f8f6c 370 int can_mode(CanMode mode) {
hudakz 0:e29bc8e0dddd 371 switch(mode) {
hudakz 0:e29bc8e0dddd 372 case MODE_RESET:
hudakz 0:e29bc8e0dddd 373 return HAL_ERROR;
hudakz 0:e29bc8e0dddd 374
hudakz 0:e29bc8e0dddd 375 case MODE_NORMAL:
hudakz 0:e29bc8e0dddd 376 _canHandle.Init.Mode = CAN_MODE_NORMAL;
hudakz 0:e29bc8e0dddd 377 break;
hudakz 0:e29bc8e0dddd 378
hudakz 0:e29bc8e0dddd 379 case MODE_SILENT:
hudakz 0:e29bc8e0dddd 380 _canHandle.Init.Mode = CAN_MODE_SILENT;
hudakz 0:e29bc8e0dddd 381 break;
hudakz 0:e29bc8e0dddd 382
hudakz 0:e29bc8e0dddd 383 case MODE_TEST_GLOBAL:
hudakz 0:e29bc8e0dddd 384 _canHandle.Init.Mode = CAN_MODE_LOOPBACK;
hudakz 0:e29bc8e0dddd 385 break;
hudakz 0:e29bc8e0dddd 386
hudakz 0:e29bc8e0dddd 387 case MODE_TEST_LOCAL:
hudakz 0:e29bc8e0dddd 388 _canHandle.Init.Mode = CAN_MODE_LOOPBACK;
hudakz 0:e29bc8e0dddd 389 break;
hudakz 0:e29bc8e0dddd 390
hudakz 0:e29bc8e0dddd 391 case MODE_TEST_SILENT:
hudakz 0:e29bc8e0dddd 392 _canHandle.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
hudakz 0:e29bc8e0dddd 393 break;
hudakz 0:e29bc8e0dddd 394 }
hudakz 0:e29bc8e0dddd 395
hudakz 3:0fae6b54a2ee 396 return HAL_CAN_Init(&_canHandle);
hudakz 0:e29bc8e0dddd 397 }
hudakz 0:e29bc8e0dddd 398
hudakz 0:e29bc8e0dddd 399 /**
hudakz 0:e29bc8e0dddd 400 * @brief
hudakz 0:e29bc8e0dddd 401 * @note
hudakz 0:e29bc8e0dddd 402 * @param
hudakz 0:e29bc8e0dddd 403 * @retval
hudakz 0:e29bc8e0dddd 404 */
hudakz 20:bcd8161f8f6c 405 int can_filter(uint32_t id, uint32_t mask, CANFormat format /*=CANAny*/, int32_t handle /*=0*/ ) {
hudakz 0:e29bc8e0dddd 406 CAN_FilterConfTypeDef sFilterConfig;
hudakz 0:e29bc8e0dddd 407
hudakz 8:5c90d6b9a382 408 sFilterConfig.FilterNumber = handle; // Specifies the filter number (must be a number between 0 and 13 at 32-bit filter scale)
hudakz 0:e29bc8e0dddd 409 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
hudakz 0:e29bc8e0dddd 410 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
hudakz 0:e29bc8e0dddd 411 sFilterConfig.FilterIdHigh = (((id) >> 16) & 0xFFFF);
hudakz 0:e29bc8e0dddd 412 sFilterConfig.FilterIdLow = ((id) & 0xFFFF);
hudakz 0:e29bc8e0dddd 413 sFilterConfig.FilterMaskIdHigh = (((mask) >> 16) & 0xFFFF);
hudakz 0:e29bc8e0dddd 414 sFilterConfig.FilterMaskIdLow = ((mask) & 0xFFFF);
hudakz 0:e29bc8e0dddd 415 sFilterConfig.FilterFIFOAssignment = 0;
hudakz 0:e29bc8e0dddd 416 sFilterConfig.FilterActivation = ENABLE;
hudakz 8:5c90d6b9a382 417 sFilterConfig.BankNumber = 0; // Selects the start bank filter
hudakz 8:5c90d6b9a382 418 return HAL_CAN_ConfigFilter(&_canHandle, &sFilterConfig);
hudakz 0:e29bc8e0dddd 419 }
hudakz 0:e29bc8e0dddd 420
hudakz 0:e29bc8e0dddd 421 /**
hudakz 0:e29bc8e0dddd 422 * @brief
hudakz 0:e29bc8e0dddd 423 * @note
hudakz 0:e29bc8e0dddd 424 * @param
hudakz 0:e29bc8e0dddd 425 * @retval
hudakz 0:e29bc8e0dddd 426 */
hudakz 20:bcd8161f8f6c 427 void can_reset(void) {
hudakz 0:e29bc8e0dddd 428 __HAL_CAN_RESET_HANDLE_STATE(&_canHandle);
hudakz 0:e29bc8e0dddd 429 }
hudakz 0:e29bc8e0dddd 430
hudakz 0:e29bc8e0dddd 431 /**
hudakz 0:e29bc8e0dddd 432 * @brief
hudakz 0:e29bc8e0dddd 433 * @note
hudakz 0:e29bc8e0dddd 434 * @param
hudakz 0:e29bc8e0dddd 435 * @retval
hudakz 0:e29bc8e0dddd 436 */
hudakz 20:bcd8161f8f6c 437 unsigned char can_rderror(void) {
hudakz 0:e29bc8e0dddd 438 return HAL_CAN_GetError(&_canHandle);
hudakz 0:e29bc8e0dddd 439 }
hudakz 0:e29bc8e0dddd 440
hudakz 0:e29bc8e0dddd 441 /**
hudakz 0:e29bc8e0dddd 442 * @brief
hudakz 0:e29bc8e0dddd 443 * @note
hudakz 0:e29bc8e0dddd 444 * @param
hudakz 0:e29bc8e0dddd 445 * @retval
hudakz 0:e29bc8e0dddd 446 */
hudakz 20:bcd8161f8f6c 447 unsigned char can_tderror(void) {
hudakz 0:e29bc8e0dddd 448 return HAL_CAN_GetError(&_canHandle);
hudakz 0:e29bc8e0dddd 449 }
hudakz 0:e29bc8e0dddd 450
hudakz 0:e29bc8e0dddd 451 /**
hudakz 0:e29bc8e0dddd 452 * @brief
hudakz 0:e29bc8e0dddd 453 * @note
hudakz 0:e29bc8e0dddd 454 * @param
hudakz 0:e29bc8e0dddd 455 * @retval
hudakz 0:e29bc8e0dddd 456 */
hudakz 20:bcd8161f8f6c 457 void can_monitor(int silent) {
hudakz 0:e29bc8e0dddd 458
hudakz 0:e29bc8e0dddd 459 // not implemented
hudakz 0:e29bc8e0dddd 460 }
hudakz 1:eb04f7f0478d 461
hudakz 5:b53e5ee15315 462
hudakz 6:c5a40d5fd9f1 463
hudakz 11:439f3a34c42e 464
hudakz 12:c45310ff2233 465
hudakz 20:bcd8161f8f6c 466
hudakz 24:c5d348e65e24 467