mbed library sources. Supersedes mbed-src. Add PORTG support for STM32L476JG (SensorTile kit)

Dependents:   SensorTileTest

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