mbed library sources. With a patch for the can_api

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
Parent:
targets/hal/TARGET_STM/TARGET_STM32F4/can_api.c@129:8a86d1aafce0
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 75:245e7931bad6 1 /* mbed Microcontroller Library
mbed_official 75:245e7931bad6 2 * Copyright (c) 2006-2016 ARM Limited
mbed_official 75:245e7931bad6 3 *
mbed_official 75:245e7931bad6 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 75:245e7931bad6 5 * you may not use this file except in compliance with the License.
mbed_official 75:245e7931bad6 6 * You may obtain a copy of the License at
mbed_official 75:245e7931bad6 7 *
mbed_official 75:245e7931bad6 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 75:245e7931bad6 9 *
mbed_official 75:245e7931bad6 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 75:245e7931bad6 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 75:245e7931bad6 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 75:245e7931bad6 13 * See the License for the specific language governing permissions and
mbed_official 75:245e7931bad6 14 * limitations under the License.
mbed_official 75:245e7931bad6 15 */
mbed_official 75:245e7931bad6 16 #include "can_api.h"
mbed_official 75:245e7931bad6 17
mbed_official 75:245e7931bad6 18 #if DEVICE_CAN
mbed_official 75:245e7931bad6 19
mbed_official 75:245e7931bad6 20 #include "cmsis.h"
mbed_official 75:245e7931bad6 21 #include "pinmap.h"
mbed_official 75:245e7931bad6 22 #include "PeripheralPins.h"
mbed_official 75:245e7931bad6 23 #include "mbed_error.h"
mbed_official 75:245e7931bad6 24 #include <math.h>
mbed_official 75:245e7931bad6 25 #include <string.h>
mbed_official 75:245e7931bad6 26
mbed_official 75:245e7931bad6 27 #define CAN_NUM 2
mbed_official 75:245e7931bad6 28 static CAN_HandleTypeDef CanHandle;
mbed_official 75:245e7931bad6 29 static uint32_t can_irq_ids[CAN_NUM] = {0};
mbed_official 75:245e7931bad6 30 static can_irq_handler irq_handler;
mbed_official 75:245e7931bad6 31
mbed_official 75:245e7931bad6 32 void can_init(can_t *obj, PinName rd, PinName td)
mbed_official 75:245e7931bad6 33 {
mbed_official 125:e632577a484c 34 uint32_t filter_number;
mbed_official 75:245e7931bad6 35 CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
mbed_official 75:245e7931bad6 36 CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
mbed_official 75:245e7931bad6 37 obj->can = (CANName)pinmap_merge(can_rd, can_td);
mbed_official 75:245e7931bad6 38 MBED_ASSERT((int)obj->can != NC);
mbed_official 75:245e7931bad6 39
mbed_official 75:245e7931bad6 40 if(obj->can == CAN_1) {
mbed_official 75:245e7931bad6 41 __HAL_RCC_CAN1_CLK_ENABLE();
mbed_official 75:245e7931bad6 42 obj->index = 0;
mbed_official 75:245e7931bad6 43 } else {
mbed_official 75:245e7931bad6 44 __HAL_RCC_CAN2_CLK_ENABLE();
mbed_official 129:8a86d1aafce0 45 obj->index = 1;
mbed_official 75:245e7931bad6 46 }
mbed_official 75:245e7931bad6 47
mbed_official 75:245e7931bad6 48 // Configure the CAN pins
mbed_official 75:245e7931bad6 49 pinmap_pinout(rd, PinMap_CAN_RD);
mbed_official 75:245e7931bad6 50 pinmap_pinout(td, PinMap_CAN_TD);
mbed_official 75:245e7931bad6 51 if (rd != NC) {
mbed_official 75:245e7931bad6 52 pin_mode(rd, PullUp);
mbed_official 75:245e7931bad6 53 }
mbed_official 75:245e7931bad6 54 if (td != NC) {
mbed_official 75:245e7931bad6 55 pin_mode(td, PullUp);
mbed_official 75:245e7931bad6 56 }
mbed_official 75:245e7931bad6 57
mbed_official 75:245e7931bad6 58 CanHandle.Instance = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 59
mbed_official 75:245e7931bad6 60 CanHandle.Init.TTCM = DISABLE;
mbed_official 75:245e7931bad6 61 CanHandle.Init.ABOM = DISABLE;
mbed_official 75:245e7931bad6 62 CanHandle.Init.AWUM = DISABLE;
mbed_official 75:245e7931bad6 63 CanHandle.Init.NART = DISABLE;
mbed_official 75:245e7931bad6 64 CanHandle.Init.RFLM = DISABLE;
mbed_official 75:245e7931bad6 65 CanHandle.Init.TXFP = DISABLE;
mbed_official 75:245e7931bad6 66 CanHandle.Init.Mode = CAN_MODE_NORMAL;
mbed_official 75:245e7931bad6 67 CanHandle.Init.SJW = CAN_SJW_1TQ;
mbed_official 75:245e7931bad6 68 CanHandle.Init.BS1 = CAN_BS1_6TQ;
mbed_official 75:245e7931bad6 69 CanHandle.Init.BS2 = CAN_BS2_8TQ;
mbed_official 75:245e7931bad6 70 CanHandle.Init.Prescaler = 2;
mbed_official 75:245e7931bad6 71
mbed_official 75:245e7931bad6 72 if (HAL_CAN_Init(&CanHandle) != HAL_OK) {
mbed_official 75:245e7931bad6 73 error("Cannot initialize CAN");
mbed_official 75:245e7931bad6 74 }
mbed_official 125:e632577a484c 75
mbed_official 125:e632577a484c 76 filter_number = (obj->can == CAN_1) ? 0 : 14;
mbed_official 125:e632577a484c 77
mbed_official 129:8a86d1aafce0 78 // Set initial CAN frequency to 100kb/s
mbed_official 129:8a86d1aafce0 79 can_frequency(obj, 100000);
mbed_official 129:8a86d1aafce0 80
mbed_official 125:e632577a484c 81 can_filter(obj, 0, 0, CANStandard, filter_number);
mbed_official 75:245e7931bad6 82 }
mbed_official 75:245e7931bad6 83
mbed_official 75:245e7931bad6 84 void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
mbed_official 75:245e7931bad6 85 {
mbed_official 75:245e7931bad6 86 irq_handler = handler;
mbed_official 75:245e7931bad6 87 can_irq_ids[obj->index] = id;
mbed_official 75:245e7931bad6 88 }
mbed_official 75:245e7931bad6 89
mbed_official 75:245e7931bad6 90 void can_irq_free(can_t *obj)
mbed_official 75:245e7931bad6 91 {
mbed_official 75:245e7931bad6 92 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 93
mbed_official 75:245e7931bad6 94 can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \
mbed_official 75:245e7931bad6 95 CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF);
mbed_official 75:245e7931bad6 96 can_irq_ids[obj->can] = 0;
mbed_official 75:245e7931bad6 97 }
mbed_official 75:245e7931bad6 98
mbed_official 75:245e7931bad6 99 void can_free(can_t *obj)
mbed_official 75:245e7931bad6 100 {
mbed_official 75:245e7931bad6 101 // Reset CAN and disable clock
mbed_official 75:245e7931bad6 102 if (obj->can == CAN_1) {
mbed_official 75:245e7931bad6 103 __HAL_RCC_CAN1_FORCE_RESET();
mbed_official 75:245e7931bad6 104 __HAL_RCC_CAN1_RELEASE_RESET();
mbed_official 75:245e7931bad6 105 __HAL_RCC_CAN1_CLK_DISABLE();
mbed_official 75:245e7931bad6 106 }
mbed_official 75:245e7931bad6 107
mbed_official 75:245e7931bad6 108 if (obj->can == CAN_2) {
mbed_official 75:245e7931bad6 109 __HAL_RCC_CAN2_FORCE_RESET();
mbed_official 75:245e7931bad6 110 __HAL_RCC_CAN2_RELEASE_RESET();
mbed_official 75:245e7931bad6 111 __HAL_RCC_CAN2_CLK_DISABLE();
mbed_official 75:245e7931bad6 112 }
mbed_official 75:245e7931bad6 113 }
mbed_official 75:245e7931bad6 114
mbed_official 75:245e7931bad6 115 // The following table is used to program bit_timing. It is an adjustment of the sample
mbed_official 75:245e7931bad6 116 // point by synchronizing on the start-bit edge and resynchronizing on the following edges.
mbed_official 75:245e7931bad6 117 // This table has the sampling points as close to 75% as possible (most commonly used).
mbed_official 75:245e7931bad6 118 // The first value is TSEG1, the second TSEG2.
mbed_official 75:245e7931bad6 119 static const int timing_pts[23][2] = {
mbed_official 75:245e7931bad6 120 {0x0, 0x0}, // 2, 50%
mbed_official 75:245e7931bad6 121 {0x1, 0x0}, // 3, 67%
mbed_official 75:245e7931bad6 122 {0x2, 0x0}, // 4, 75%
mbed_official 75:245e7931bad6 123 {0x3, 0x0}, // 5, 80%
mbed_official 75:245e7931bad6 124 {0x3, 0x1}, // 6, 67%
mbed_official 75:245e7931bad6 125 {0x4, 0x1}, // 7, 71%
mbed_official 75:245e7931bad6 126 {0x5, 0x1}, // 8, 75%
mbed_official 75:245e7931bad6 127 {0x6, 0x1}, // 9, 78%
mbed_official 75:245e7931bad6 128 {0x6, 0x2}, // 10, 70%
mbed_official 75:245e7931bad6 129 {0x7, 0x2}, // 11, 73%
mbed_official 75:245e7931bad6 130 {0x8, 0x2}, // 12, 75%
mbed_official 75:245e7931bad6 131 {0x9, 0x2}, // 13, 77%
mbed_official 75:245e7931bad6 132 {0x9, 0x3}, // 14, 71%
mbed_official 75:245e7931bad6 133 {0xA, 0x3}, // 15, 73%
mbed_official 75:245e7931bad6 134 {0xB, 0x3}, // 16, 75%
mbed_official 75:245e7931bad6 135 {0xC, 0x3}, // 17, 76%
mbed_official 75:245e7931bad6 136 {0xD, 0x3}, // 18, 78%
mbed_official 75:245e7931bad6 137 {0xD, 0x4}, // 19, 74%
mbed_official 75:245e7931bad6 138 {0xE, 0x4}, // 20, 75%
mbed_official 75:245e7931bad6 139 {0xF, 0x4}, // 21, 76%
mbed_official 75:245e7931bad6 140 {0xF, 0x5}, // 22, 73%
mbed_official 75:245e7931bad6 141 {0xF, 0x6}, // 23, 70%
mbed_official 75:245e7931bad6 142 {0xF, 0x7}, // 24, 67%
mbed_official 75:245e7931bad6 143 };
mbed_official 75:245e7931bad6 144
mbed_official 75:245e7931bad6 145 static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw)
mbed_official 75:245e7931bad6 146 {
mbed_official 75:245e7931bad6 147 uint32_t btr;
mbed_official 75:245e7931bad6 148 uint16_t brp = 0;
mbed_official 75:245e7931bad6 149 uint32_t calcbit;
mbed_official 75:245e7931bad6 150 uint32_t bitwidth;
mbed_official 75:245e7931bad6 151 int hit = 0;
mbed_official 75:245e7931bad6 152 int bits;
mbed_official 75:245e7931bad6 153
mbed_official 75:245e7931bad6 154 bitwidth = (pclk / cclk);
mbed_official 75:245e7931bad6 155
mbed_official 75:245e7931bad6 156 brp = bitwidth / 0x18;
mbed_official 75:245e7931bad6 157 while ((!hit) && (brp < bitwidth / 4)) {
mbed_official 75:245e7931bad6 158 brp++;
mbed_official 75:245e7931bad6 159 for (bits = 22; bits > 0; bits--) {
mbed_official 75:245e7931bad6 160 calcbit = (bits + 3) * (brp + 1);
mbed_official 75:245e7931bad6 161 if (calcbit == bitwidth) {
mbed_official 75:245e7931bad6 162 hit = 1;
mbed_official 75:245e7931bad6 163 break;
mbed_official 75:245e7931bad6 164 }
mbed_official 75:245e7931bad6 165 }
mbed_official 75:245e7931bad6 166 }
mbed_official 75:245e7931bad6 167
mbed_official 75:245e7931bad6 168 if (hit) {
mbed_official 75:245e7931bad6 169 btr = ((timing_pts[bits][1] << 20) & 0x00700000)
mbed_official 75:245e7931bad6 170 | ((timing_pts[bits][0] << 16) & 0x000F0000)
mbed_official 75:245e7931bad6 171 | ((psjw << 24) & 0x0000C000)
mbed_official 75:245e7931bad6 172 | ((brp << 0) & 0x000003FF);
mbed_official 75:245e7931bad6 173 } else {
mbed_official 75:245e7931bad6 174 btr = 0xFFFFFFFF;
mbed_official 75:245e7931bad6 175 }
mbed_official 75:245e7931bad6 176
mbed_official 75:245e7931bad6 177 return btr;
mbed_official 75:245e7931bad6 178
mbed_official 75:245e7931bad6 179 }
mbed_official 75:245e7931bad6 180
mbed_official 75:245e7931bad6 181 int can_frequency(can_t *obj, int f)
mbed_official 75:245e7931bad6 182 {
mbed_official 129:8a86d1aafce0 183 int pclk = HAL_RCC_GetPCLK1Freq();
mbed_official 75:245e7931bad6 184 int btr = can_speed(pclk, (unsigned int)f, 1);
mbed_official 75:245e7931bad6 185 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 186
mbed_official 75:245e7931bad6 187 if (btr > 0) {
mbed_official 75:245e7931bad6 188 can->MCR |= CAN_MCR_INRQ ;
mbed_official 75:245e7931bad6 189 while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) {
mbed_official 75:245e7931bad6 190 }
mbed_official 75:245e7931bad6 191 can->BTR = btr;
mbed_official 75:245e7931bad6 192 can->MCR &= ~(uint32_t)CAN_MCR_INRQ;
mbed_official 75:245e7931bad6 193 while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
mbed_official 75:245e7931bad6 194 }
mbed_official 75:245e7931bad6 195 return 1;
mbed_official 75:245e7931bad6 196 } else {
mbed_official 75:245e7931bad6 197 return 0;
mbed_official 75:245e7931bad6 198 }
mbed_official 75:245e7931bad6 199 }
mbed_official 75:245e7931bad6 200
mbed_official 75:245e7931bad6 201 int can_write(can_t *obj, CAN_Message msg, int cc)
mbed_official 75:245e7931bad6 202 {
mbed_official 75:245e7931bad6 203 uint32_t transmitmailbox = 5;
mbed_official 75:245e7931bad6 204 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 205
mbed_official 75:245e7931bad6 206 /* Select one empty transmit mailbox */
mbed_official 75:245e7931bad6 207 if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) {
mbed_official 75:245e7931bad6 208 transmitmailbox = 0;
mbed_official 75:245e7931bad6 209 } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) {
mbed_official 75:245e7931bad6 210 transmitmailbox = 1;
mbed_official 75:245e7931bad6 211 } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) {
mbed_official 75:245e7931bad6 212 transmitmailbox = 2;
mbed_official 75:245e7931bad6 213 } else {
mbed_official 75:245e7931bad6 214 transmitmailbox = CAN_TXSTATUS_NOMAILBOX;
mbed_official 75:245e7931bad6 215 }
mbed_official 75:245e7931bad6 216
mbed_official 75:245e7931bad6 217 if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) {
mbed_official 75:245e7931bad6 218 can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ;
mbed_official 75:245e7931bad6 219 if (!(msg.format))
mbed_official 75:245e7931bad6 220 {
mbed_official 75:245e7931bad6 221 can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type);
mbed_official 75:245e7931bad6 222 }
mbed_official 75:245e7931bad6 223 else
mbed_official 75:245e7931bad6 224 {
mbed_official 75:245e7931bad6 225 can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type);
mbed_official 75:245e7931bad6 226 }
mbed_official 75:245e7931bad6 227
mbed_official 75:245e7931bad6 228 /* Set up the DLC */
mbed_official 75:245e7931bad6 229 can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0;
mbed_official 75:245e7931bad6 230 can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F);
mbed_official 75:245e7931bad6 231
mbed_official 75:245e7931bad6 232 /* Set up the data field */
mbed_official 75:245e7931bad6 233 can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) |
mbed_official 75:245e7931bad6 234 ((uint32_t)msg.data[2] << 16) |
mbed_official 75:245e7931bad6 235 ((uint32_t)msg.data[1] << 8) |
mbed_official 75:245e7931bad6 236 ((uint32_t)msg.data[0]));
mbed_official 75:245e7931bad6 237 can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) |
mbed_official 75:245e7931bad6 238 ((uint32_t)msg.data[6] << 16) |
mbed_official 75:245e7931bad6 239 ((uint32_t)msg.data[5] << 8) |
mbed_official 75:245e7931bad6 240 ((uint32_t)msg.data[4]));
mbed_official 75:245e7931bad6 241 /* Request transmission */
mbed_official 75:245e7931bad6 242 can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
mbed_official 75:245e7931bad6 243 }
mbed_official 75:245e7931bad6 244
mbed_official 75:245e7931bad6 245 return 1;
mbed_official 75:245e7931bad6 246 }
mbed_official 75:245e7931bad6 247
mbed_official 75:245e7931bad6 248 int can_read(can_t *obj, CAN_Message *msg, int handle)
mbed_official 75:245e7931bad6 249 {
mbed_official 75:245e7931bad6 250 //handle is the FIFO number
mbed_official 75:245e7931bad6 251
mbed_official 75:245e7931bad6 252 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 253
mbed_official 75:245e7931bad6 254 /* Get the Id */
mbed_official 75:245e7931bad6 255 msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR);
mbed_official 75:245e7931bad6 256 if (!msg->format) {
mbed_official 75:245e7931bad6 257 msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21);
mbed_official 75:245e7931bad6 258 } else {
mbed_official 75:245e7931bad6 259 msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3);
mbed_official 75:245e7931bad6 260 }
mbed_official 75:245e7931bad6 261
mbed_official 75:245e7931bad6 262 msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR);
mbed_official 75:245e7931bad6 263 /* Get the DLC */
mbed_official 75:245e7931bad6 264 msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR;
mbed_official 75:245e7931bad6 265 // /* Get the FMI */
mbed_official 75:245e7931bad6 266 // msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8);
mbed_official 75:245e7931bad6 267 /* Get the data field */
mbed_official 75:245e7931bad6 268 msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR;
mbed_official 75:245e7931bad6 269 msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8);
mbed_official 75:245e7931bad6 270 msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16);
mbed_official 75:245e7931bad6 271 msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24);
mbed_official 75:245e7931bad6 272 msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR;
mbed_official 75:245e7931bad6 273 msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8);
mbed_official 75:245e7931bad6 274 msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16);
mbed_official 75:245e7931bad6 275 msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24);
mbed_official 75:245e7931bad6 276
mbed_official 75:245e7931bad6 277 /* Release the FIFO */
mbed_official 75:245e7931bad6 278 if(handle == CAN_FIFO0) {
mbed_official 75:245e7931bad6 279 /* Release FIFO0 */
mbed_official 75:245e7931bad6 280 can->RF0R = CAN_RF0R_RFOM0;
mbed_official 75:245e7931bad6 281 } else { /* FIFONumber == CAN_FIFO1 */
mbed_official 75:245e7931bad6 282 /* Release FIFO1 */
mbed_official 75:245e7931bad6 283 can->RF1R = CAN_RF1R_RFOM1;
mbed_official 75:245e7931bad6 284 }
mbed_official 75:245e7931bad6 285
mbed_official 75:245e7931bad6 286 return 1;
mbed_official 75:245e7931bad6 287 }
mbed_official 75:245e7931bad6 288
mbed_official 75:245e7931bad6 289 void can_reset(can_t *obj)
mbed_official 75:245e7931bad6 290 {
mbed_official 75:245e7931bad6 291 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 292
mbed_official 75:245e7931bad6 293 can->MCR |= CAN_MCR_RESET;
mbed_official 75:245e7931bad6 294 can->ESR = 0x0;
mbed_official 75:245e7931bad6 295 }
mbed_official 75:245e7931bad6 296
mbed_official 75:245e7931bad6 297 unsigned char can_rderror(can_t *obj)
mbed_official 75:245e7931bad6 298 {
mbed_official 75:245e7931bad6 299 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 300 return (can->ESR >> 24) & 0xFF;
mbed_official 75:245e7931bad6 301 }
mbed_official 75:245e7931bad6 302
mbed_official 75:245e7931bad6 303 unsigned char can_tderror(can_t *obj)
mbed_official 75:245e7931bad6 304 {
mbed_official 75:245e7931bad6 305 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 306 return (can->ESR >> 16) & 0xFF;
mbed_official 75:245e7931bad6 307 }
mbed_official 75:245e7931bad6 308
mbed_official 75:245e7931bad6 309 void can_monitor(can_t *obj, int silent)
mbed_official 75:245e7931bad6 310 {
mbed_official 75:245e7931bad6 311 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 312
mbed_official 75:245e7931bad6 313 can->MCR |= CAN_MCR_INRQ ;
mbed_official 75:245e7931bad6 314 while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) {
mbed_official 75:245e7931bad6 315 }
mbed_official 75:245e7931bad6 316 if (silent) {
mbed_official 75:245e7931bad6 317 can->BTR |= ((uint32_t)1 << 31);
mbed_official 75:245e7931bad6 318 } else {
mbed_official 75:245e7931bad6 319 can->BTR &= ~((uint32_t)1 << 31);
mbed_official 75:245e7931bad6 320 }
mbed_official 75:245e7931bad6 321 can->MCR &= ~(uint32_t)CAN_MCR_INRQ;
mbed_official 75:245e7931bad6 322 while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
mbed_official 75:245e7931bad6 323 }
mbed_official 75:245e7931bad6 324 }
mbed_official 75:245e7931bad6 325
mbed_official 75:245e7931bad6 326 int can_mode(can_t *obj, CanMode mode)
mbed_official 75:245e7931bad6 327 {
mbed_official 75:245e7931bad6 328 int success = 0;
mbed_official 75:245e7931bad6 329 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 330 can->MCR |= CAN_MCR_INRQ ;
mbed_official 75:245e7931bad6 331 while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) {
mbed_official 75:245e7931bad6 332 }
mbed_official 75:245e7931bad6 333 switch (mode) {
mbed_official 75:245e7931bad6 334 case MODE_NORMAL:
mbed_official 75:245e7931bad6 335 can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM);
mbed_official 75:245e7931bad6 336 success = 1;
mbed_official 75:245e7931bad6 337 break;
mbed_official 75:245e7931bad6 338 case MODE_SILENT:
mbed_official 75:245e7931bad6 339 can->BTR |= CAN_BTR_SILM;
mbed_official 75:245e7931bad6 340 can->BTR &= ~CAN_BTR_LBKM;
mbed_official 75:245e7931bad6 341 success = 1;
mbed_official 75:245e7931bad6 342 break;
mbed_official 75:245e7931bad6 343 case MODE_TEST_GLOBAL:
mbed_official 75:245e7931bad6 344 case MODE_TEST_LOCAL:
mbed_official 75:245e7931bad6 345 can->BTR |= CAN_BTR_LBKM;
mbed_official 75:245e7931bad6 346 can->BTR &= ~CAN_BTR_SILM;
mbed_official 75:245e7931bad6 347 success = 1;
mbed_official 75:245e7931bad6 348 break;
mbed_official 75:245e7931bad6 349 case MODE_TEST_SILENT:
mbed_official 75:245e7931bad6 350 can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM);
mbed_official 75:245e7931bad6 351 success = 1;
mbed_official 75:245e7931bad6 352 break;
mbed_official 75:245e7931bad6 353 default:
mbed_official 75:245e7931bad6 354 success = 0;
mbed_official 75:245e7931bad6 355 break;
mbed_official 75:245e7931bad6 356 }
mbed_official 75:245e7931bad6 357 can->MCR &= ~(uint32_t)CAN_MCR_INRQ;
mbed_official 75:245e7931bad6 358 while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) {
mbed_official 75:245e7931bad6 359 }
mbed_official 75:245e7931bad6 360 return success;
mbed_official 75:245e7931bad6 361 }
mbed_official 75:245e7931bad6 362
mbed_official 75:245e7931bad6 363 int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
mbed_official 75:245e7931bad6 364 {
mbed_official 75:245e7931bad6 365 CanHandle.Instance = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 366 CAN_FilterConfTypeDef sFilterConfig;
mbed_official 75:245e7931bad6 367
mbed_official 75:245e7931bad6 368 sFilterConfig.FilterNumber = handle;
mbed_official 75:245e7931bad6 369 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
mbed_official 75:245e7931bad6 370 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
mbed_official 75:245e7931bad6 371 sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8);
mbed_official 75:245e7931bad6 372 sFilterConfig.FilterIdLow = (uint8_t) id;
mbed_official 75:245e7931bad6 373 sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8);
mbed_official 75:245e7931bad6 374 sFilterConfig.FilterMaskIdLow = (uint8_t) mask;
mbed_official 75:245e7931bad6 375 sFilterConfig.FilterFIFOAssignment = 0;
mbed_official 75:245e7931bad6 376 sFilterConfig.FilterActivation = ENABLE;
mbed_official 75:245e7931bad6 377 sFilterConfig.BankNumber = 14 + handle;
mbed_official 75:245e7931bad6 378
mbed_official 75:245e7931bad6 379 HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig);
mbed_official 75:245e7931bad6 380
mbed_official 75:245e7931bad6 381 return 0;
mbed_official 75:245e7931bad6 382 }
mbed_official 75:245e7931bad6 383
mbed_official 75:245e7931bad6 384 static void can_irq(CANName name, int id)
mbed_official 75:245e7931bad6 385 {
mbed_official 75:245e7931bad6 386 uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0;
mbed_official 75:245e7931bad6 387 CanHandle.Instance = (CAN_TypeDef *)name;
mbed_official 75:245e7931bad6 388
mbed_official 75:245e7931bad6 389 if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) {
mbed_official 75:245e7931bad6 390 tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0);
mbed_official 75:245e7931bad6 391 tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1);
mbed_official 75:245e7931bad6 392 tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2);
mbed_official 75:245e7931bad6 393 if(tmp1 || tmp2 || tmp3)
mbed_official 75:245e7931bad6 394 {
mbed_official 75:245e7931bad6 395 irq_handler(can_irq_ids[id], IRQ_TX);
mbed_official 75:245e7931bad6 396 }
mbed_official 75:245e7931bad6 397 }
mbed_official 75:245e7931bad6 398
mbed_official 75:245e7931bad6 399 tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0);
mbed_official 75:245e7931bad6 400 tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0);
mbed_official 75:245e7931bad6 401
mbed_official 75:245e7931bad6 402 if((tmp1 != 0) && tmp2) {
mbed_official 75:245e7931bad6 403 irq_handler(can_irq_ids[id], IRQ_RX);
mbed_official 75:245e7931bad6 404 }
mbed_official 75:245e7931bad6 405
mbed_official 75:245e7931bad6 406 tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV);
mbed_official 75:245e7931bad6 407 tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV);
mbed_official 75:245e7931bad6 408 tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
mbed_official 75:245e7931bad6 409
mbed_official 75:245e7931bad6 410 if(tmp1 && tmp2 && tmp3) {
mbed_official 75:245e7931bad6 411 irq_handler(can_irq_ids[id], IRQ_PASSIVE);
mbed_official 75:245e7931bad6 412 }
mbed_official 75:245e7931bad6 413
mbed_official 75:245e7931bad6 414 tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF);
mbed_official 75:245e7931bad6 415 tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF);
mbed_official 75:245e7931bad6 416 tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
mbed_official 75:245e7931bad6 417 if(tmp1 && tmp2 && tmp3) {
mbed_official 75:245e7931bad6 418 irq_handler(can_irq_ids[id], IRQ_BUS);
mbed_official 75:245e7931bad6 419 }
mbed_official 75:245e7931bad6 420
mbed_official 75:245e7931bad6 421 tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR);
mbed_official 75:245e7931bad6 422 if(tmp1 && tmp2 && tmp3) {
mbed_official 75:245e7931bad6 423 irq_handler(can_irq_ids[id], IRQ_ERROR);
mbed_official 75:245e7931bad6 424 }
mbed_official 75:245e7931bad6 425 }
mbed_official 75:245e7931bad6 426
mbed_official 75:245e7931bad6 427 void CAN1_RX0_IRQHandler(void)
mbed_official 75:245e7931bad6 428 {
mbed_official 75:245e7931bad6 429 can_irq(CAN_1, 0);
mbed_official 75:245e7931bad6 430 }
mbed_official 75:245e7931bad6 431
mbed_official 75:245e7931bad6 432 void CAN1_TX_IRQHandler(void)
mbed_official 75:245e7931bad6 433 {
mbed_official 75:245e7931bad6 434 can_irq(CAN_1, 0);
mbed_official 75:245e7931bad6 435 }
mbed_official 75:245e7931bad6 436
mbed_official 75:245e7931bad6 437 void CAN1_SCE_IRQHandler(void)
mbed_official 75:245e7931bad6 438 {
mbed_official 75:245e7931bad6 439 can_irq(CAN_1, 0);
mbed_official 75:245e7931bad6 440 }
mbed_official 75:245e7931bad6 441
mbed_official 75:245e7931bad6 442 void CAN2_RX0_IRQHandler(void)
mbed_official 75:245e7931bad6 443 {
mbed_official 75:245e7931bad6 444 can_irq(CAN_2, 1);
mbed_official 75:245e7931bad6 445 }
mbed_official 75:245e7931bad6 446
mbed_official 75:245e7931bad6 447 void CAN2_TX_IRQHandler(void)
mbed_official 75:245e7931bad6 448 {
mbed_official 75:245e7931bad6 449 can_irq(CAN_2, 1);
mbed_official 75:245e7931bad6 450 }
mbed_official 75:245e7931bad6 451
mbed_official 75:245e7931bad6 452 void CAN2_SCE_IRQHandler(void)
mbed_official 75:245e7931bad6 453 {
mbed_official 75:245e7931bad6 454 can_irq(CAN_2, 1);
mbed_official 75:245e7931bad6 455 }
mbed_official 75:245e7931bad6 456
mbed_official 75:245e7931bad6 457 void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
mbed_official 75:245e7931bad6 458 {
mbed_official 75:245e7931bad6 459
mbed_official 75:245e7931bad6 460 CAN_TypeDef *can = (CAN_TypeDef *)(obj->can);
mbed_official 75:245e7931bad6 461 IRQn_Type irq_n = (IRQn_Type)0;
mbed_official 75:245e7931bad6 462 uint32_t vector = 0;
mbed_official 75:245e7931bad6 463 uint32_t ier;
mbed_official 75:245e7931bad6 464
mbed_official 75:245e7931bad6 465 if(obj->can == CAN_1) {
mbed_official 75:245e7931bad6 466 switch (type) {
mbed_official 75:245e7931bad6 467 case IRQ_RX:
mbed_official 75:245e7931bad6 468 ier = CAN_IT_FMP0;
mbed_official 75:245e7931bad6 469 irq_n = CAN1_RX0_IRQn;
mbed_official 75:245e7931bad6 470 vector = (uint32_t)&CAN1_RX0_IRQHandler;
mbed_official 75:245e7931bad6 471 break;
mbed_official 75:245e7931bad6 472 case IRQ_TX:
mbed_official 75:245e7931bad6 473 ier = CAN_IT_TME;
mbed_official 75:245e7931bad6 474 irq_n = CAN1_TX_IRQn;
mbed_official 75:245e7931bad6 475 vector = (uint32_t)&CAN1_TX_IRQHandler;
mbed_official 75:245e7931bad6 476 break;
mbed_official 75:245e7931bad6 477 case IRQ_ERROR:
mbed_official 75:245e7931bad6 478 ier = CAN_IT_ERR;
mbed_official 75:245e7931bad6 479 irq_n = CAN1_SCE_IRQn;
mbed_official 75:245e7931bad6 480 vector = (uint32_t)&CAN1_SCE_IRQHandler;
mbed_official 75:245e7931bad6 481 break;
mbed_official 75:245e7931bad6 482 case IRQ_PASSIVE:
mbed_official 75:245e7931bad6 483 ier = CAN_IT_EPV;
mbed_official 75:245e7931bad6 484 irq_n = CAN1_SCE_IRQn;
mbed_official 75:245e7931bad6 485 vector = (uint32_t)&CAN1_SCE_IRQHandler;
mbed_official 75:245e7931bad6 486 break;
mbed_official 75:245e7931bad6 487 case IRQ_BUS:
mbed_official 75:245e7931bad6 488 ier = CAN_IT_BOF;
mbed_official 75:245e7931bad6 489 irq_n = CAN1_SCE_IRQn;
mbed_official 75:245e7931bad6 490 vector = (uint32_t)&CAN1_SCE_IRQHandler;
mbed_official 75:245e7931bad6 491 break;
mbed_official 75:245e7931bad6 492 default: return;
mbed_official 75:245e7931bad6 493 }
mbed_official 75:245e7931bad6 494 } else {
mbed_official 75:245e7931bad6 495 switch (type) {
mbed_official 75:245e7931bad6 496 case IRQ_RX:
mbed_official 75:245e7931bad6 497 ier = CAN_IT_FMP0;
mbed_official 75:245e7931bad6 498 irq_n = CAN2_RX0_IRQn;
mbed_official 75:245e7931bad6 499 vector = (uint32_t)&CAN2_RX0_IRQHandler;
mbed_official 75:245e7931bad6 500 break;
mbed_official 75:245e7931bad6 501 case IRQ_TX:
mbed_official 75:245e7931bad6 502 ier = CAN_IT_TME;
mbed_official 75:245e7931bad6 503 irq_n = CAN2_TX_IRQn;
mbed_official 75:245e7931bad6 504 vector = (uint32_t)&CAN2_TX_IRQHandler;
mbed_official 75:245e7931bad6 505 break;
mbed_official 75:245e7931bad6 506 case IRQ_ERROR:
mbed_official 75:245e7931bad6 507 ier = CAN_IT_ERR;
mbed_official 75:245e7931bad6 508 irq_n = CAN2_SCE_IRQn;
mbed_official 75:245e7931bad6 509 vector = (uint32_t)&CAN2_SCE_IRQHandler;
mbed_official 75:245e7931bad6 510 break;
mbed_official 75:245e7931bad6 511 case IRQ_PASSIVE:
mbed_official 75:245e7931bad6 512 ier = CAN_IT_EPV;
mbed_official 75:245e7931bad6 513 irq_n = CAN2_SCE_IRQn;
mbed_official 75:245e7931bad6 514 vector = (uint32_t)&CAN2_SCE_IRQHandler;
mbed_official 75:245e7931bad6 515 break;
mbed_official 75:245e7931bad6 516 case IRQ_BUS:
mbed_official 75:245e7931bad6 517 ier = CAN_IT_BOF;
mbed_official 75:245e7931bad6 518 irq_n = CAN2_SCE_IRQn;
mbed_official 75:245e7931bad6 519 vector = (uint32_t)&CAN2_SCE_IRQHandler;
mbed_official 75:245e7931bad6 520 break;
mbed_official 75:245e7931bad6 521 default: return;
mbed_official 75:245e7931bad6 522 }
mbed_official 75:245e7931bad6 523 }
mbed_official 75:245e7931bad6 524
mbed_official 75:245e7931bad6 525 if(enable) {
mbed_official 75:245e7931bad6 526 can->IER |= ier;
mbed_official 75:245e7931bad6 527 } else {
mbed_official 75:245e7931bad6 528 can->IER &= ~ier;
mbed_official 75:245e7931bad6 529 }
mbed_official 75:245e7931bad6 530
mbed_official 75:245e7931bad6 531 NVIC_SetVector(irq_n, vector);
mbed_official 75:245e7931bad6 532 NVIC_EnableIRQ(irq_n);
mbed_official 75:245e7931bad6 533 }
mbed_official 75:245e7931bad6 534
mbed_official 75:245e7931bad6 535 #endif // DEVICE_CAN
mbed_official 75:245e7931bad6 536