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