Modification of Mbed-dev library for LQFP48 package microcontrollers: STM32F103C8 (STM32F103C8T6) and STM32F103CB (STM32F103CBT6) (Bluepill boards, Maple mini etc. )

Fork of mbed-STM32F103C8_org by Nothing Special

Library for STM32F103C8 (Bluepill boards etc.).
Use this instead of mbed library.
This library allows the size of the code in the FLASH up to 128kB. Therefore, code also runs on microcontrollers STM32F103CB (eg. Maple mini).
But in the case of STM32F103C8, check the size of the resulting code would not exceed 64kB.

To compile a program with this library, use NUCLEO-F103RB as the target name. !

Changes:

  • Corrected initialization of the HSE + crystal clock (mbed permanent bug), allowing the use of on-board xtal (8MHz).(1)
  • Additionally, it also set USB clock (48Mhz).(2)
  • Definitions of pins and peripherals adjusted to LQFP48 case.
  • Board led LED1 is now PC_13 (3)
  • USER_BUTTON is now PC_14 (4)

    Now the library is complete rebuilt based on mbed-dev v160 (and not yet fully tested).

notes
(1) - In case 8MHz xtal on board, CPU frequency is 72MHz. Without xtal is 64MHz.
(2) - Using the USB interface is only possible if STM32 is clocking by on-board 8MHz xtal or external clock signal 8MHz on the OSC_IN pin.
(3) - On Bluepill board led operation is reversed, i.e. 0 - led on, 1 - led off.
(4) - Bluepill board has no real user button

Information

After export to SW4STM (AC6):

  • add line #include "mbed_config.h" in files Serial.h and RawSerial.h
  • in project properties change Optimisation Level to Optimise for size (-Os)
Committer:
mega64
Date:
Thu Apr 27 23:56:38 2017 +0000
Revision:
148:8b0b02bf146f
Parent:
146:03e976389d16
Remove unnecessary folders

Who changed what in which revision?

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