mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Fri Sep 11 09:30:09 2015 +0100
Revision:
621:9c82b0f79f3d
Parent:
554:edd95c0879f8
Synchronized with git revision 6c1d63e069ab9bd86de92e8296ca783681257538

Full URL: https://github.com/mbedmicro/mbed/commit/6c1d63e069ab9bd86de92e8296ca783681257538/

ignore target files not supported by the yotta module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 554:edd95c0879f8 1 /* mbed Microcontroller Library
mbed_official 554:edd95c0879f8 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 554:edd95c0879f8 3 *
mbed_official 554:edd95c0879f8 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 554:edd95c0879f8 5 * you may not use this file except in compliance with the License.
mbed_official 554:edd95c0879f8 6 * You may obtain a copy of the License at
mbed_official 554:edd95c0879f8 7 *
mbed_official 554:edd95c0879f8 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 554:edd95c0879f8 9 *
mbed_official 554:edd95c0879f8 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 554:edd95c0879f8 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 554:edd95c0879f8 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 554:edd95c0879f8 13 * See the License for the specific language governing permissions and
mbed_official 554:edd95c0879f8 14 * limitations under the License.
mbed_official 554:edd95c0879f8 15 */
mbed_official 554:edd95c0879f8 16 #include "mbed_assert.h"
mbed_official 554:edd95c0879f8 17 #include "can_api.h"
mbed_official 554:edd95c0879f8 18 #include "cmsis.h"
mbed_official 554:edd95c0879f8 19 #include "pinmap.h"
mbed_official 554:edd95c0879f8 20
mbed_official 554:edd95c0879f8 21 #include <math.h>
mbed_official 554:edd95c0879f8 22 #include <string.h>
mbed_official 554:edd95c0879f8 23
mbed_official 554:edd95c0879f8 24 /* Acceptance filter mode in AFMR register */
mbed_official 554:edd95c0879f8 25 #define ACCF_OFF 0x01
mbed_official 554:edd95c0879f8 26 #define ACCF_BYPASS 0x02
mbed_official 554:edd95c0879f8 27 #define ACCF_ON 0x00
mbed_official 554:edd95c0879f8 28 #define ACCF_FULLCAN 0x04
mbed_official 554:edd95c0879f8 29
mbed_official 554:edd95c0879f8 30 /* There are several bit timing calculators on the internet.
mbed_official 554:edd95c0879f8 31 http://www.port.de/engl/canprod/sv_req_form.html
mbed_official 554:edd95c0879f8 32 http://www.kvaser.com/can/index.htm
mbed_official 554:edd95c0879f8 33 */
mbed_official 554:edd95c0879f8 34
mbed_official 554:edd95c0879f8 35 static const PinMap PinMap_CAN_RD[] = {
mbed_official 554:edd95c0879f8 36 {P0_0 , CAN_1, 1},
mbed_official 554:edd95c0879f8 37 {P0_4 , CAN_2, 2},
mbed_official 554:edd95c0879f8 38 {P0_21, CAN_1, 3},
mbed_official 554:edd95c0879f8 39 {P2_7 , CAN_2, 1},
mbed_official 554:edd95c0879f8 40 {NC , NC , 0}
mbed_official 554:edd95c0879f8 41 };
mbed_official 554:edd95c0879f8 42
mbed_official 554:edd95c0879f8 43 static const PinMap PinMap_CAN_TD[] = {
mbed_official 554:edd95c0879f8 44 {P0_1 , CAN_1, 1},
mbed_official 554:edd95c0879f8 45 {P0_5 , CAN_2, 2},
mbed_official 554:edd95c0879f8 46 {P0_22, CAN_1, 3},
mbed_official 554:edd95c0879f8 47 {P2_8 , CAN_2, 1},
mbed_official 554:edd95c0879f8 48 {NC , NC , 0}
mbed_official 554:edd95c0879f8 49 };
mbed_official 554:edd95c0879f8 50
mbed_official 554:edd95c0879f8 51 // Type definition to hold a CAN message
mbed_official 554:edd95c0879f8 52 struct CANMsg {
mbed_official 554:edd95c0879f8 53 unsigned int reserved1 : 16;
mbed_official 554:edd95c0879f8 54 unsigned int dlc : 4; // Bits 16..19: DLC - Data Length Counter
mbed_official 554:edd95c0879f8 55 unsigned int reserved0 : 10;
mbed_official 554:edd95c0879f8 56 unsigned int rtr : 1; // Bit 30: Set if this is a RTR message
mbed_official 554:edd95c0879f8 57 unsigned int type : 1; // Bit 31: Set if this is a 29-bit ID message
mbed_official 554:edd95c0879f8 58 unsigned int id; // CAN Message ID (11-bit or 29-bit)
mbed_official 554:edd95c0879f8 59 unsigned char data[8]; // CAN Message Data Bytes 0-7
mbed_official 554:edd95c0879f8 60 };
mbed_official 554:edd95c0879f8 61 typedef struct CANMsg CANMsg;
mbed_official 554:edd95c0879f8 62
mbed_official 554:edd95c0879f8 63 static uint32_t can_disable(can_t *obj) {
mbed_official 554:edd95c0879f8 64 uint32_t sm = obj->dev->MOD;
mbed_official 554:edd95c0879f8 65 obj->dev->MOD |= 1;
mbed_official 554:edd95c0879f8 66 return sm;
mbed_official 554:edd95c0879f8 67 }
mbed_official 554:edd95c0879f8 68
mbed_official 554:edd95c0879f8 69 static inline void can_enable(can_t *obj) {
mbed_official 554:edd95c0879f8 70 if (obj->dev->MOD & 1) {
mbed_official 554:edd95c0879f8 71 obj->dev->MOD &= ~(1);
mbed_official 554:edd95c0879f8 72 }
mbed_official 554:edd95c0879f8 73 }
mbed_official 554:edd95c0879f8 74
mbed_official 554:edd95c0879f8 75 int can_mode(can_t *obj, CanMode mode) {
mbed_official 554:edd95c0879f8 76 return 0; // not implemented
mbed_official 554:edd95c0879f8 77 }
mbed_official 554:edd95c0879f8 78
mbed_official 554:edd95c0879f8 79 int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
mbed_official 554:edd95c0879f8 80 return 0; // not implemented
mbed_official 554:edd95c0879f8 81 }
mbed_official 554:edd95c0879f8 82
mbed_official 554:edd95c0879f8 83 static int can_pclk(can_t *obj) {
mbed_official 554:edd95c0879f8 84 int value = 0;
mbed_official 554:edd95c0879f8 85 switch ((int)obj->dev) {
mbed_official 554:edd95c0879f8 86 case CAN_1: value = (LPC_SC->PCLKSEL0 & (0x3 << 26)) >> 26; break;
mbed_official 554:edd95c0879f8 87 case CAN_2: value = (LPC_SC->PCLKSEL0 & (0x3 << 28)) >> 28; break;
mbed_official 554:edd95c0879f8 88 }
mbed_official 554:edd95c0879f8 89
mbed_official 554:edd95c0879f8 90 switch (value) {
mbed_official 554:edd95c0879f8 91 case 1: return 1;
mbed_official 554:edd95c0879f8 92 case 2: return 2;
mbed_official 554:edd95c0879f8 93 case 3: return 6;
mbed_official 554:edd95c0879f8 94 default: return 4;
mbed_official 554:edd95c0879f8 95 }
mbed_official 554:edd95c0879f8 96 }
mbed_official 554:edd95c0879f8 97
mbed_official 554:edd95c0879f8 98 // This table has the sampling points as close to 75% as possible. The first
mbed_official 554:edd95c0879f8 99 // value is TSEG1, the second TSEG2.
mbed_official 554:edd95c0879f8 100 static const int timing_pts[23][2] = {
mbed_official 554:edd95c0879f8 101 {0x0, 0x0}, // 2, 50%
mbed_official 554:edd95c0879f8 102 {0x1, 0x0}, // 3, 67%
mbed_official 554:edd95c0879f8 103 {0x2, 0x0}, // 4, 75%
mbed_official 554:edd95c0879f8 104 {0x3, 0x0}, // 5, 80%
mbed_official 554:edd95c0879f8 105 {0x3, 0x1}, // 6, 67%
mbed_official 554:edd95c0879f8 106 {0x4, 0x1}, // 7, 71%
mbed_official 554:edd95c0879f8 107 {0x5, 0x1}, // 8, 75%
mbed_official 554:edd95c0879f8 108 {0x6, 0x1}, // 9, 78%
mbed_official 554:edd95c0879f8 109 {0x6, 0x2}, // 10, 70%
mbed_official 554:edd95c0879f8 110 {0x7, 0x2}, // 11, 73%
mbed_official 554:edd95c0879f8 111 {0x8, 0x2}, // 12, 75%
mbed_official 554:edd95c0879f8 112 {0x9, 0x2}, // 13, 77%
mbed_official 554:edd95c0879f8 113 {0x9, 0x3}, // 14, 71%
mbed_official 554:edd95c0879f8 114 {0xA, 0x3}, // 15, 73%
mbed_official 554:edd95c0879f8 115 {0xB, 0x3}, // 16, 75%
mbed_official 554:edd95c0879f8 116 {0xC, 0x3}, // 17, 76%
mbed_official 554:edd95c0879f8 117 {0xD, 0x3}, // 18, 78%
mbed_official 554:edd95c0879f8 118 {0xD, 0x4}, // 19, 74%
mbed_official 554:edd95c0879f8 119 {0xE, 0x4}, // 20, 75%
mbed_official 554:edd95c0879f8 120 {0xF, 0x4}, // 21, 76%
mbed_official 554:edd95c0879f8 121 {0xF, 0x5}, // 22, 73%
mbed_official 554:edd95c0879f8 122 {0xF, 0x6}, // 23, 70%
mbed_official 554:edd95c0879f8 123 {0xF, 0x7}, // 24, 67%
mbed_official 554:edd95c0879f8 124 };
mbed_official 554:edd95c0879f8 125
mbed_official 554:edd95c0879f8 126 static unsigned int can_speed(unsigned int sclk, unsigned int pclk, unsigned int cclk, unsigned char psjw) {
mbed_official 554:edd95c0879f8 127 uint32_t btr;
mbed_official 554:edd95c0879f8 128 uint16_t brp = 0;
mbed_official 554:edd95c0879f8 129 uint32_t calcbit;
mbed_official 554:edd95c0879f8 130 uint32_t bitwidth;
mbed_official 554:edd95c0879f8 131 int hit = 0;
mbed_official 554:edd95c0879f8 132 int bits;
mbed_official 554:edd95c0879f8 133
mbed_official 554:edd95c0879f8 134 bitwidth = sclk / (pclk * cclk);
mbed_official 554:edd95c0879f8 135
mbed_official 554:edd95c0879f8 136 brp = bitwidth / 0x18;
mbed_official 554:edd95c0879f8 137 while ((!hit) && (brp < bitwidth / 4)) {
mbed_official 554:edd95c0879f8 138 brp++;
mbed_official 554:edd95c0879f8 139 for (bits = 22; bits > 0; bits--) {
mbed_official 554:edd95c0879f8 140 calcbit = (bits + 3) * (brp + 1);
mbed_official 554:edd95c0879f8 141 if (calcbit == bitwidth) {
mbed_official 554:edd95c0879f8 142 hit = 1;
mbed_official 554:edd95c0879f8 143 break;
mbed_official 554:edd95c0879f8 144 }
mbed_official 554:edd95c0879f8 145 }
mbed_official 554:edd95c0879f8 146 }
mbed_official 554:edd95c0879f8 147
mbed_official 554:edd95c0879f8 148 if (hit) {
mbed_official 554:edd95c0879f8 149 btr = ((timing_pts[bits][1] << 20) & 0x00700000)
mbed_official 554:edd95c0879f8 150 | ((timing_pts[bits][0] << 16) & 0x000F0000)
mbed_official 554:edd95c0879f8 151 | ((psjw << 14) & 0x0000C000)
mbed_official 554:edd95c0879f8 152 | ((brp << 0) & 0x000003FF);
mbed_official 554:edd95c0879f8 153 } else {
mbed_official 554:edd95c0879f8 154 btr = 0xFFFFFFFF;
mbed_official 554:edd95c0879f8 155 }
mbed_official 554:edd95c0879f8 156
mbed_official 554:edd95c0879f8 157 return btr;
mbed_official 554:edd95c0879f8 158 }
mbed_official 554:edd95c0879f8 159
mbed_official 554:edd95c0879f8 160 void can_init(can_t *obj, PinName rd, PinName td) {
mbed_official 554:edd95c0879f8 161 CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD);
mbed_official 554:edd95c0879f8 162 CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD);
mbed_official 554:edd95c0879f8 163 obj->dev = (LPC_CAN_TypeDef *)pinmap_merge(can_rd, can_td);
mbed_official 554:edd95c0879f8 164 MBED_ASSERT((int)obj->dev != NC);
mbed_official 554:edd95c0879f8 165
mbed_official 554:edd95c0879f8 166 switch ((int)obj->dev) {
mbed_official 554:edd95c0879f8 167 case CAN_1: LPC_SC->PCONP |= 1 << PCAN1; break;
mbed_official 554:edd95c0879f8 168 case CAN_2: LPC_SC->PCONP |= 1 << PCAN2; break;
mbed_official 554:edd95c0879f8 169 }
mbed_official 554:edd95c0879f8 170
mbed_official 554:edd95c0879f8 171 pinmap_pinout(rd, PinMap_CAN_RD);
mbed_official 554:edd95c0879f8 172 pinmap_pinout(td, PinMap_CAN_TD);
mbed_official 554:edd95c0879f8 173
mbed_official 554:edd95c0879f8 174 can_reset(obj);
mbed_official 554:edd95c0879f8 175 obj->dev->IER = 0; // Disable Interrupts
mbed_official 554:edd95c0879f8 176 can_frequency(obj, 100000);
mbed_official 554:edd95c0879f8 177
mbed_official 554:edd95c0879f8 178 LPC_CANAF->AFMR = ACCF_BYPASS; // Bypass Filter
mbed_official 554:edd95c0879f8 179 }
mbed_official 554:edd95c0879f8 180
mbed_official 554:edd95c0879f8 181 void can_free(can_t *obj) {
mbed_official 554:edd95c0879f8 182 switch ((int)obj->dev) {
mbed_official 554:edd95c0879f8 183 case CAN_1: LPC_SC->PCONP &= ~(1 << PCAN1); break;
mbed_official 554:edd95c0879f8 184 case CAN_2: LPC_SC->PCONP &= ~(1 << PCAN2); break;
mbed_official 554:edd95c0879f8 185 }
mbed_official 554:edd95c0879f8 186 }
mbed_official 554:edd95c0879f8 187
mbed_official 554:edd95c0879f8 188 int can_frequency(can_t *obj, int f) {
mbed_official 554:edd95c0879f8 189 int pclk = can_pclk(obj);
mbed_official 554:edd95c0879f8 190 int btr = can_speed(SystemCoreClock, pclk, (unsigned int)f, 1);
mbed_official 554:edd95c0879f8 191
mbed_official 554:edd95c0879f8 192 if (btr > 0) {
mbed_official 554:edd95c0879f8 193 uint32_t modmask = can_disable(obj);
mbed_official 554:edd95c0879f8 194 obj->dev->BTR = btr;
mbed_official 554:edd95c0879f8 195 obj->dev->MOD = modmask;
mbed_official 554:edd95c0879f8 196 return 1;
mbed_official 554:edd95c0879f8 197 } else {
mbed_official 554:edd95c0879f8 198 return 0;
mbed_official 554:edd95c0879f8 199 }
mbed_official 554:edd95c0879f8 200 }
mbed_official 554:edd95c0879f8 201
mbed_official 554:edd95c0879f8 202 int can_write(can_t *obj, CAN_Message msg, int cc) {
mbed_official 554:edd95c0879f8 203 unsigned int CANStatus;
mbed_official 554:edd95c0879f8 204 CANMsg m;
mbed_official 554:edd95c0879f8 205
mbed_official 554:edd95c0879f8 206 can_enable(obj);
mbed_official 554:edd95c0879f8 207
mbed_official 554:edd95c0879f8 208 m.id = msg.id ;
mbed_official 554:edd95c0879f8 209 m.dlc = msg.len & 0xF;
mbed_official 554:edd95c0879f8 210 m.rtr = msg.type;
mbed_official 554:edd95c0879f8 211 m.type = msg.format;
mbed_official 554:edd95c0879f8 212 memcpy(m.data, msg.data, msg.len);
mbed_official 554:edd95c0879f8 213 const unsigned int *buf = (const unsigned int *)&m;
mbed_official 554:edd95c0879f8 214
mbed_official 554:edd95c0879f8 215 CANStatus = obj->dev->SR;
mbed_official 554:edd95c0879f8 216 if (CANStatus & 0x00000004) {
mbed_official 554:edd95c0879f8 217 obj->dev->TFI1 = buf[0] & 0xC00F0000;
mbed_official 554:edd95c0879f8 218 obj->dev->TID1 = buf[1];
mbed_official 554:edd95c0879f8 219 obj->dev->TDA1 = buf[2];
mbed_official 554:edd95c0879f8 220 obj->dev->TDB1 = buf[3];
mbed_official 554:edd95c0879f8 221 if (cc) {
mbed_official 554:edd95c0879f8 222 obj->dev->CMR = 0x30;
mbed_official 554:edd95c0879f8 223 } else {
mbed_official 554:edd95c0879f8 224 obj->dev->CMR = 0x21;
mbed_official 554:edd95c0879f8 225 }
mbed_official 554:edd95c0879f8 226 return 1;
mbed_official 554:edd95c0879f8 227
mbed_official 554:edd95c0879f8 228 } else if (CANStatus & 0x00000400) {
mbed_official 554:edd95c0879f8 229 obj->dev->TFI2 = buf[0] & 0xC00F0000;
mbed_official 554:edd95c0879f8 230 obj->dev->TID2 = buf[1];
mbed_official 554:edd95c0879f8 231 obj->dev->TDA2 = buf[2];
mbed_official 554:edd95c0879f8 232 obj->dev->TDB2 = buf[3];
mbed_official 554:edd95c0879f8 233 if (cc) {
mbed_official 554:edd95c0879f8 234 obj->dev->CMR = 0x50;
mbed_official 554:edd95c0879f8 235 } else {
mbed_official 554:edd95c0879f8 236 obj->dev->CMR = 0x41;
mbed_official 554:edd95c0879f8 237 }
mbed_official 554:edd95c0879f8 238 return 1;
mbed_official 554:edd95c0879f8 239
mbed_official 554:edd95c0879f8 240 } else if (CANStatus & 0x00040000) {
mbed_official 554:edd95c0879f8 241 obj->dev->TFI3 = buf[0] & 0xC00F0000;
mbed_official 554:edd95c0879f8 242 obj->dev->TID3 = buf[1];
mbed_official 554:edd95c0879f8 243 obj->dev->TDA3 = buf[2];
mbed_official 554:edd95c0879f8 244 obj->dev->TDB3 = buf[3];
mbed_official 554:edd95c0879f8 245 if (cc) {
mbed_official 554:edd95c0879f8 246 obj->dev->CMR = 0x90;
mbed_official 554:edd95c0879f8 247 } else {
mbed_official 554:edd95c0879f8 248 obj->dev->CMR = 0x81;
mbed_official 554:edd95c0879f8 249 }
mbed_official 554:edd95c0879f8 250 return 1;
mbed_official 554:edd95c0879f8 251 }
mbed_official 554:edd95c0879f8 252
mbed_official 554:edd95c0879f8 253 return 0;
mbed_official 554:edd95c0879f8 254 }
mbed_official 554:edd95c0879f8 255
mbed_official 554:edd95c0879f8 256 int can_read(can_t *obj, CAN_Message *msg, int handle) {
mbed_official 554:edd95c0879f8 257 CANMsg x;
mbed_official 554:edd95c0879f8 258 unsigned int *i = (unsigned int *)&x;
mbed_official 554:edd95c0879f8 259
mbed_official 554:edd95c0879f8 260 can_enable(obj);
mbed_official 554:edd95c0879f8 261
mbed_official 554:edd95c0879f8 262 if (obj->dev->GSR & 0x1) {
mbed_official 554:edd95c0879f8 263 *i++ = obj->dev->RFS; // Frame
mbed_official 554:edd95c0879f8 264 *i++ = obj->dev->RID; // ID
mbed_official 554:edd95c0879f8 265 *i++ = obj->dev->RDA; // Data A
mbed_official 554:edd95c0879f8 266 *i++ = obj->dev->RDB; // Data B
mbed_official 554:edd95c0879f8 267 obj->dev->CMR = 0x04; // release receive buffer
mbed_official 554:edd95c0879f8 268
mbed_official 554:edd95c0879f8 269 msg->id = x.id;
mbed_official 554:edd95c0879f8 270 msg->len = x.dlc;
mbed_official 554:edd95c0879f8 271 msg->format = (x.type)? CANExtended : CANStandard;
mbed_official 554:edd95c0879f8 272 msg->type = (x.rtr)? CANRemote: CANData;
mbed_official 554:edd95c0879f8 273 memcpy(msg->data,x.data,x.dlc);
mbed_official 554:edd95c0879f8 274 return 1;
mbed_official 554:edd95c0879f8 275 }
mbed_official 554:edd95c0879f8 276
mbed_official 554:edd95c0879f8 277 return 0;
mbed_official 554:edd95c0879f8 278 }
mbed_official 554:edd95c0879f8 279
mbed_official 554:edd95c0879f8 280 void can_reset(can_t *obj) {
mbed_official 554:edd95c0879f8 281 can_disable(obj);
mbed_official 554:edd95c0879f8 282 obj->dev->GSR = 0; // Reset error counter when CAN1MOD is in reset
mbed_official 554:edd95c0879f8 283 }
mbed_official 554:edd95c0879f8 284
mbed_official 554:edd95c0879f8 285 unsigned char can_rderror(can_t *obj) {
mbed_official 554:edd95c0879f8 286 return (obj->dev->GSR >> 16) & 0xFF;
mbed_official 554:edd95c0879f8 287 }
mbed_official 554:edd95c0879f8 288
mbed_official 554:edd95c0879f8 289 unsigned char can_tderror(can_t *obj) {
mbed_official 554:edd95c0879f8 290 return (obj->dev->GSR >> 24) & 0xFF;
mbed_official 554:edd95c0879f8 291 }
mbed_official 554:edd95c0879f8 292
mbed_official 554:edd95c0879f8 293 void can_monitor(can_t *obj, int silent) {
mbed_official 554:edd95c0879f8 294 uint32_t mod_mask = can_disable(obj);
mbed_official 554:edd95c0879f8 295 if (silent) {
mbed_official 554:edd95c0879f8 296 obj->dev->MOD |= (1 << 1);
mbed_official 554:edd95c0879f8 297 } else {
mbed_official 554:edd95c0879f8 298 obj->dev->MOD &= ~(1 << 1);
mbed_official 554:edd95c0879f8 299 }
mbed_official 554:edd95c0879f8 300 if (!(mod_mask & 1)) {
mbed_official 554:edd95c0879f8 301 can_enable(obj);
mbed_official 554:edd95c0879f8 302 }
mbed_official 554:edd95c0879f8 303 }