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 SEEED_CAN by
seeed_can_api.cpp
00001 /* seeed_can_api.cpp 00002 * Copyright (c) 2013 Sophie Dexter 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "seeed_can_api.h" 00018 00019 /** Initialise the MCP2515 and set the bit rate 00020 */ 00021 uint8_t mcpInit(mcp_can_t *obj, const uint32_t bitRate, const CANMode mode) 00022 { 00023 union { // Access CANMsg as: 00024 CANMsg x; // the organised struct 00025 uint8_t y[]; // or contiguous memory array 00026 }; 00027 uint8_t maskFilt[8] = { MCP_RXM0SIDH, MCP_RXM1SIDH, MCP_RXF0SIDH, MCP_RXF1SIDH, MCP_RXF2SIDH, MCP_RXF3SIDH, MCP_RXF4SIDH, MCP_RXF5SIDH }; 00028 uint8_t canBufCtrl[5] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL, MCP_RXB0CTRL, MCP_RXB1CTRL }; 00029 uint8_t canBuffer[3] = { MCP_TXB0CTRL+1, MCP_TXB1CTRL+1, MCP_TXB2CTRL+1 }; 00030 00031 #ifdef DEBUG 00032 printf("Reseting MCP2515\r\n"); 00033 #endif 00034 mcpReset(obj); 00035 for (uint32_t i = 0; i < 8; i++) { // Clear all CAN id masks and filters 00036 mcpWriteId(obj, maskFilt[i], NULL, NULL); 00037 } 00038 for (uint32_t i = 0; i < 5; i++) { // Clear all CAN buffer control registers 00039 mcpWrite(obj, canBufCtrl[i], NULL); 00040 } 00041 for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise empty CAN message buffer 00042 for (uint32_t i = 0; i < 3; i++) { // Clear all CAN TX buffers 00043 mcpWriteMultiple(obj, canBuffer[i], y, sizeof(x) ); // using empty CAN message (as an array) 00044 } 00045 // enable both receive-buffers, using filters to receive messages with std. and ext. identifiers that meet the filter criteria and enable rollover from RXB0 to RXB1 if RXB0 is full 00046 mcpBitModify(obj, MCP_RXB0CTRL, MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK, MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK ); 00047 mcpBitModify(obj, MCP_RXB1CTRL, MCP_RXB_RX_MASK, MCP_RXB_RX_STDEXT); 00048 #ifdef DEBUG 00049 printf("Setting bit rate\r\n"); 00050 #endif 00051 if (!mcpSetBitRate(obj, bitRate)) { // set baudrate 00052 return 0; 00053 } 00054 // return mcpSetMode(obj, MODE_NORMAL) ? 1 : 0; // set Normal mode and return 00055 return mcpSetMode(obj, mode) ? 1 : 0; // set Normal mode and return 00056 } 00057 00058 /** set MCP2515 operation mode 00059 * 00060 * Configuration, Normal, Sleep, Listen-only or Loopback 00061 */ 00062 uint8_t mcpSetMode(mcp_can_t *obj, const uint8_t newmode) 00063 { 00064 mcpBitModify(obj, MCP_CANCTRL, MODE_MASK, newmode); 00065 for (uint32_t i = 0; i<10; i++) { 00066 if ((mcpRead(obj, MCP_CANSTAT) & MODE_MASK) == newmode) { 00067 #ifdef DEBUG 00068 printf("Successfully entered mode: %02x time: %dms\r\n", newmode, i); 00069 printf("CANCTRL:%02x CANSTAT:%02x TXB0:%02x TXB1:%02x TXB2:%02x\r\n", mcpRead(obj, MCP_CANCTRL), mcpRead(obj, MCP_CANSTAT), mcpRead(obj, MCP_TXB0CTRL), mcpRead(obj, MCP_TXB1CTRL), mcpRead(obj, MCP_TXB2CTRL)); 00070 #endif 00071 return 1; 00072 } 00073 wait_ms(1); 00074 } 00075 #ifdef DEBUG 00076 printf("Failed to enter mode: %02x\r\n", newmode); 00077 printf("CANCTRL:%02x CANSTAT:%02x TXB0:%02x TXB1:%02x TXB2:%02x\r\n", mcpRead(obj, MCP_CANCTRL), mcpRead(obj, MCP_CANSTAT), mcpRead(obj, MCP_TXB0CTRL), mcpRead(obj, MCP_TXB1CTRL), mcpRead(obj, MCP_TXB2CTRL)); 00078 #endif 00079 return 0; 00080 } 00081 00082 /** set the CAN bus bitrate 00083 * 00084 * Calculate suitable BTR register values. 00085 * The Bit Rate Pre-scaler (BRP) can be in the range of 1-64. 00086 * According to CANopen, Bit Time can be be between 25 and 8 Time Quanta (TQU). 00087 * Bit Time = SyncSeg(1 TQU) + PropSeg(1-8 TQU) + PhaseSeg1(1-8 TQU) + PhaseSeg2(2-8 TQU). 00088 * SyncSeg is always 1TQU, PhaseSeg2 must be at least 2TQU to be longer than the processing time. 00089 * Opinions vary on when to take a sample but a point roughly 2/3 of Bit Time seems OK. 00090 * Synchronisation Jump width can be 1-4 TQU, a value of 1 seems to be normal. 00091 * 00092 * All register values are -1, e.g. PropSeg can range from 1-8 TQU, so values are 0-7 (0-63 for BRP). 00093 * 00094 * This table has the sampling points as close to 2/3 (66.7%) as possible. 00095 * The first value is PropSeg, 2nd PhaseSeg1. 00096 * PhaseSeg2 will be the same as PhaseSeg1 when btlmode bit is initialised to 0. 00097 */ 00098 static const uint8_t timing_pts[18][2] = { 00099 {0x0, 0x2}, // 8, 62.5% 00100 {0x1, 0x2}, // 9, 66.7% 00101 {0x2, 0x2}, // 10, 70.0% 00102 {0x1, 0x3}, // 11, 63.6% 00103 {0x2, 0x3}, // 12, 66.7% 00104 {0x3, 0x3}, // 13, 69.2% 00105 {0x2, 0x4}, // 14, 64.3% 00106 {0x3, 0x4}, // 15, 66.7% 00107 {0x4, 0x4}, // 16, 68.75% 00108 {0x3, 0x5}, // 17, 64.7% 00109 {0x4, 0x5}, // 18, 66.7% 00110 {0x5, 0x5}, // 19, 63.2% 00111 {0x4, 0x6}, // 20, 65.0% 00112 {0x5, 0x6}, // 21, 66.7% 00113 {0x6, 0x6}, // 22, 68.2% 00114 {0x5, 0x7}, // 23, 65.2 00115 {0x6, 0x7}, // 24, 66.7% 00116 {0x7, 0x7}, // 25, 68.0% 00117 }; 00118 00119 uint8_t mcpSetBitRate(mcp_can_t *obj, const uint32_t bitRate) 00120 { 00121 union { // Access CANtiming as: 00122 CANtiming x; // the organised struct 00123 uint8_t y[]; // or contiguous memory array 00124 }; 00125 uint32_t bestBRP = 0; 00126 uint32_t bestTQU = 0; 00127 uint32_t bestCanRate = 0; 00128 uint32_t minBRP = (MCP_CLOCK_FREQ / (2 * MCP_MAX_TIME_QUANTA * bitRate)); 00129 uint32_t maxBRP = (MCP_CLOCK_FREQ / (2 * MCP_MIN_TIME_QUANTA * bitRate)); 00130 00131 #ifdef DEBUG 00132 printf("Setting configuration mode\r\n"); 00133 #endif 00134 uint8_t initialMode = mcpRead(obj, MCP_CANCTRL) & MODE_MASK; // Store the current operation mode 00135 if(!mcpSetMode(obj, MODE_CONFIG)) { // Go into configuration mode 00136 return 0; 00137 } 00138 00139 for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise CANtiming (btlmode, sjw and sam all = 0) 00140 if ((bitRate < CAN_MIN_RATE) || (bitRate > CAN_MAX_RATE)) { 00141 #ifdef DEBUG 00142 printf("FAILED!! The requested Bit Rate is too high or too low: %d\r\n", bitRate); 00143 #endif 00144 return 0; // Cannot set the requested bit rate! 00145 } 00146 minBRP = (minBRP == 0) ? MCP_MIN_PRESCALER : minBRP; 00147 maxBRP = (maxBRP > MCP_MAX_PRESCALER) ? MCP_MAX_PRESCALER : maxBRP; 00148 for (uint32_t BRP = minBRP; BRP < (maxBRP + 1); BRP++) { 00149 uint32_t timeQuanta = (MCP_CLOCK_FREQ / (2 * BRP * bitRate)); 00150 if ((timeQuanta >= MCP_MIN_TIME_QUANTA) && (timeQuanta <= MCP_MAX_TIME_QUANTA)) { 00151 for (uint32_t TQU = timeQuanta; TQU <= MCP_MAX_TIME_QUANTA; TQU++) { 00152 uint32_t thisCanRate = MCP_CLOCK_FREQ / (2 * BRP * TQU); 00153 if ( abs((int)bitRate - (int)thisCanRate) < abs((int)bitRate - (int)bestCanRate)) { 00154 bestCanRate = thisCanRate; 00155 bestBRP= BRP; 00156 bestTQU= TQU; 00157 } 00158 } 00159 } 00160 } 00161 x.brp = (bestBRP - 1); 00162 x.prseg = (timing_pts[bestTQU - 8][0]); 00163 x.phseg1 = (timing_pts[bestTQU - 8][1]); 00164 mcpWriteMultiple(obj, MCP_CNF3, y, sizeof(x) ); // Copy CANtiming to the MCP2515 (as an array) 00165 #ifdef DEBUG 00166 printf("minBRP %d maxBRP %d\r\n", minBRP, maxBRP); 00167 printf("Bitrate: %d\tactualBitRate: %d\t Error: %1.2f percent.\r\n", bitRate, bestCanRate, (100-(100*(float)bitRate/(float)bestCanRate))); 00168 printf("TimeQuanta: %d\tbitRatePrescaler: %d\tSamplePoint: %2.2f percent\r\n", bestTQU, bestBRP, 100*(float)(3 + x.prseg + x.phseg1)/(float)bestTQU ) ; 00169 printf("Syncseg: 1\tPropSeg: %d\tPhaseSeg1: %d\tPhaseSeg2: %d\r\n", (x.prseg+1), (x.phseg1+1), (x.phseg1+1)); 00170 printf("Setting normal mode\r\n"); 00171 #endif 00172 return (mcpSetMode(obj, initialMode)) ? 1 : 0; // desired bit rate set enter normal mode and return 00173 } 00174 00175 /** write a CAN id to a mask, filter or transmit buffer 00176 */ 00177 void mcpWriteId(mcp_can_t *obj, const uint8_t mcp_addr, const uint8_t ext, const uint32_t id ) 00178 { 00179 union { // Access CANid as: 00180 CANid x; // the organised struct 00181 uint8_t y[]; // or contiguous memory array 00182 }; 00183 00184 for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise CANid structure 00185 x.ide = ext; // Extended Identifier Flag 00186 if (x.ide == CANExtended) { 00187 x.sid10_3 = (uint8_t) (id >> 21); // SID10..3 00188 x.sid2_0 = (uint8_t) (id >> 18) & 0x07; // SID2..0 00189 x.eid17_16 = (uint8_t) (id >> 16) & 0x03; // EID17..16 00190 x.eid15_8 = (uint8_t) (id >> 8); // EID15..8 00191 x.eid7_0 = (uint8_t) id; // EID7..0 00192 } else { 00193 x.sid10_3 = (uint8_t) (id >> 3); // SID10..3 00194 x.sid2_0 = (uint8_t) (id & 0x07); // SID2..0 00195 } 00196 #ifdef DEBUG 00197 printf("sizeof CanIdStruct: %d bytes\r\n", sizeof(x)); 00198 printf("sid10_3: %x\r\n", x.sid10_3); 00199 printf("eid17_16: %x\r\n", x.eid17_16); 00200 printf("ide: %x\r\n", x.ide); 00201 printf("srtr: %x\r\n", x.srtr); 00202 printf("sid2_0: %x\r\n", x.sid2_0); 00203 printf("eid15_8: %x\r\n", x.eid15_8); 00204 printf("eid7_0: %x\r\n", x.eid7_0); 00205 #endif 00206 mcpWriteMultiple(obj, mcp_addr, y, sizeof(x) ); // Copy CANid to the MCP2515 (as an array) 00207 } 00208 00209 /** write a CAN message to the MCP2515 00210 */ 00211 uint8_t mcpCanWrite(mcp_can_t *obj, CAN_Message msg) 00212 { 00213 union { // Access CANMsg as: 00214 CANMsg x; // the organised struct 00215 uint8_t y[]; // or contiguous memory array 00216 }; 00217 uint8_t bufferCommand[] = {MCP_WRITE_TX0, MCP_WRITE_TX1, MCP_WRITE_TX2}; 00218 uint8_t rtsCommand[] = {MCP_RTS_TX0, MCP_RTS_TX1, MCP_RTS_TX2}; 00219 uint8_t status = mcpStatus(obj); 00220 uint32_t num = 0; 00221 // Check if there is a free message buffer 00222 if (!(status & MCP_STAT_TX0REQ)) { // TX Message Buffer 0 free? 00223 num = 0; 00224 } else if (!(status & MCP_STAT_TX1REQ)) { // TX Message Buffer 1 free? 00225 num = 1; 00226 } else if (!(status & MCP_STAT_TX2REQ)) { // TX Message Buffer 2 free? 00227 num = 2; 00228 } else { 00229 return 0; // No free transmit buffers in the MCP2515 CAN controller chip 00230 } 00231 // populate CANMsg structure 00232 for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise CANMsg structure 00233 x.id.ide = msg.format; // Extended Identifier Flag 00234 if (x.id.ide == CANExtended) { 00235 x.id.sid10_3 = (uint8_t) (msg.id >> 21); // SID10..3 00236 x.id.sid2_0 = (uint8_t) (msg.id >> 18) & 0x07; // SID2..0 00237 x.id.eid17_16 = (uint8_t) (msg.id >> 16) & 0x03; // EID17..16 00238 x.id.eid15_8 = (uint8_t) (msg.id >> 8); // EID15..8 00239 x.id.eid7_0 = (uint8_t) msg.id; // EID7..0 00240 } else { 00241 x.id.sid10_3 = (uint8_t) (msg.id >> 3); // SID10..3 00242 x.id.sid2_0 = (uint8_t) (msg.id & 0x07); // SID2..0 00243 } 00244 x.dlc = msg.len & 0x0f; // Number of bytes in can message 00245 x.ertr = msg.type; // Data or remote message 00246 memcpy(x.data,msg.data,x.dlc); // Get the Data bytes 00247 // write CANmsg to the specified TX buffer 'num' 00248 mcpWriteBuffer(obj, bufferCommand[num], y, sizeof(x)); // Write the message ,CANMsg, to the MCP2515's Tx buffer 'num' (as an array) 00249 mcpBufferRTS(obj, rtsCommand[num]); 00250 return 1; // Indicate that message has been transmitted 00251 } 00252 00253 /** read a CAN message from the MCP2515 00254 */ 00255 uint8_t mcpCanRead(mcp_can_t *obj, CAN_Message *msg) 00256 { 00257 union { // Access CANMsg as: 00258 CANMsg x; // the organised struct 00259 uint8_t y[]; // or contiguous memory array 00260 }; 00261 uint8_t bufferCommand[] = {MCP_READ_RX0, MCP_READ_RX1}; 00262 uint8_t status = mcpReceiveStatus(obj); 00263 bool num = 0; 00264 // Check if there is a message the buffers 00265 if (status & MCP_RXSTAT_RXB0) { // Msg in Buffer 0? 00266 num = 0; 00267 } else if (status & MCP_RXSTAT_RXB1) { // Msg in Buffer 1? 00268 num = 1; 00269 } else { 00270 return 0; // No messages waiting 00271 } 00272 mcpReadBuffer(obj, bufferCommand[0], y, sizeof(x)); // Read the message into CANMsg (as an array) 00273 mcpBitModify(obj, MCP_CANINTF, (!num ? MCP_RX0IF : MCP_RX1IF), 0); // Free the message buffer 00274 #ifdef DEBUG 00275 printf("sizeof CanMsgStruct: %d bytes\r\n", sizeof(x)); 00276 printf("sizeof CanMsgArray: %d bytes\r\n", sizeof(y)); 00277 printf("sid10_3: %x\r\n", x.id.sid10_3); 00278 printf("eid17_16: %x\r\n", x.id.eid17_16); 00279 printf("ide: %x\r\n", x.id.ide); 00280 printf("srtr: %x\r\n", x.id.srtr); 00281 printf("sid2_0: %x\r\n", x.id.sid2_0); 00282 printf("eid15_8: %x\r\n", x.id.eid15_8); 00283 printf("eid7_0: %x\r\n", x.id.eid7_0); 00284 printf("dlc: %x\r\n", x.dlc); 00285 printf("ertr: %x\r\n", x.ertr); 00286 printf("data: "); 00287 for (char i=0; i<8; i++) 00288 printf("%02x,", x.data[i]); 00289 printf("\r\n"); 00290 #endif 00291 msg->format = (status & MCP_RXSTAT_IDE) ? CANExtended : CANStandard;// Extended CAN id Flag 00292 if (msg->format == CANExtended) { // Assemble the Extended CAN id 00293 msg->id = (x.id.sid10_3 << 21) | 00294 (x.id.sid2_0 << 18) | 00295 (x.id.eid17_16 << 16) | 00296 (x.id.eid15_8 << 8) | 00297 (x.id.eid7_0); 00298 } else { // Assemble the Standard CAN id 00299 msg->id = (x.id.sid10_3 << 3) | 00300 (x.id.sid2_0); 00301 } 00302 msg->len = x.dlc; // Number of bytes in CAN message 00303 msg->type = (status & MCP_RXSTAT_RTR) ? CANRemote : CANData; // Determine if a Remote or Data message type 00304 memcpy(msg->data,x.data,x.dlc); // Get the Data bytes 00305 return 1; // Indicate that message has been retrieved 00306 } 00307 00308 /** initialise an Acceptance Mask 00309 */ 00310 uint8_t mcpInitMask(mcp_can_t *obj, uint8_t num, uint32_t ulData, bool ext) 00311 { 00312 uint8_t mask[2] = { MCP_RXM0SIDH, MCP_RXM1SIDH }; 00313 00314 if (num > 1) { 00315 #ifdef DEBUG 00316 printf("Trying to set an invalid Mask number: %d\r\n", num); 00317 #endif 00318 return 0; 00319 } 00320 #ifdef DEBUG 00321 printf("Begin to set Mask!!\r\n"); 00322 #endif 00323 uint8_t initialMode = mcpRead(obj, MCP_CANCTRL) & MODE_MASK; // Store the current operation mode 00324 if(!mcpSetMode(obj, MODE_CONFIG)) { 00325 return 0; 00326 } 00327 mcpWriteId(obj, mask[num], ext, ulData); 00328 if(!mcpSetMode(obj, initialMode)) { 00329 return 0; 00330 } 00331 #ifdef DEBUG 00332 printf("Successfully set Mask number: %d\r\n", num); 00333 #endif 00334 return 1; 00335 } 00336 00337 /** initialise an Acceptance Filter 00338 */ 00339 uint8_t mcpInitFilter(mcp_can_t *obj, uint8_t num, uint32_t ulData, bool ext) 00340 { 00341 uint8_t filter[6] = { MCP_RXF0SIDH, MCP_RXF1SIDH, MCP_RXF2SIDH, MCP_RXF3SIDH, MCP_RXF4SIDH, MCP_RXF5SIDH }; 00342 00343 if (num > 5) { 00344 #ifdef DEBUG 00345 printf("Trying to set an invalid Filter number: %d\r\n", num); 00346 #endif 00347 return 0; 00348 } 00349 #ifdef DEBUG 00350 printf("Begin to set Filter!!\r\n"); 00351 #endif 00352 uint8_t initialMode = mcpRead(obj, MCP_CANCTRL) & MODE_MASK; // Store the current operation mode 00353 if(!mcpSetMode(obj, MODE_CONFIG)) { 00354 return 0; 00355 } 00356 mcpWriteId(obj, filter[num], ext, ulData); 00357 if(!mcpSetMode(obj, initialMode)) { 00358 return 0; 00359 } 00360 #ifdef DEBUG 00361 printf("Successfully set Filter: %d\r\n", num); 00362 #endif 00363 return 1; 00364 } 00365 00366 /* Report on the specified errors and warnings 00367 */ 00368 uint8_t mcpErrorType(mcp_can_t *obj, const CANFlags type) 00369 { 00370 uint8_t which[] = { MCP_EFLG_ALLMASK, 00371 MCP_EFLG_ERRORMASK, 00372 MCP_EFLG_WARNMASK, 00373 MCP_EFLG_RX1OVR, 00374 MCP_EFLG_RX0OVR, 00375 MCP_EFLG_TXBO, 00376 MCP_EFLG_TXEP, 00377 MCP_EFLG_RXEP, 00378 MCP_EFLG_TXWAR, 00379 MCP_EFLG_RXWAR, 00380 MCP_EFLG_EWARN 00381 }; 00382 00383 return (mcpRead(obj, MCP_EFLG) & which[type]) ? 1 : 0; 00384 } 00385 00386 /* Return contents of the error and warning flags register 00387 */ 00388 uint8_t mcpErrorFlags(mcp_can_t *obj) 00389 { 00390 return (mcpRead(obj, MCP_EFLG)); 00391 } 00392 00393 /* Number of message reception errors 00394 */ 00395 uint8_t mcpReceptionErrorCount(mcp_can_t *obj) 00396 { 00397 return (mcpRead(obj, MCP_REC)); 00398 } 00399 00400 /* Number of message transmission errors 00401 */ 00402 uint8_t mcpTransmissionErrorCount(mcp_can_t *obj) 00403 { 00404 return (mcpRead(obj, MCP_TEC)); 00405 } 00406 00407 /* Select between monitor (silent = 1) and normal (silent = 0) modes 00408 */ 00409 void mcpMonitor(mcp_can_t *obj, const bool silent) 00410 { 00411 silent ? mcpSetMode(obj, MODE_LISTENONLY) : mcpSetMode(obj, MODE_NORMAL); 00412 } 00413 00414 /* Change CAN operation to the specified mode 00415 */ 00416 uint8_t mcpMode(mcp_can_t *obj, const CANMode mode) 00417 { 00418 uint8_t which[] = { MODE_NORMAL, 00419 MODE_SLEEP, 00420 MODE_LOOPBACK, 00421 MODE_LISTENONLY, 00422 MODE_CONFIG, 00423 MODE_CONFIG 00424 }; 00425 00426 if (mode == _M_RESET) { 00427 mcpReset(obj); 00428 } 00429 if (mcpSetMode(obj, which[mode])) { 00430 return 1; 00431 } 00432 return 0; 00433 } 00434 00435 /* Configure interrupt sources 00436 */ 00437 void mcpSetInterrupts(mcp_can_t *obj, const CANIrqs irqSet) 00438 { 00439 uint8_t which[] = { MCP_NO_INTS, 00440 MCP_ALL_INTS, 00441 MCP_RX_INTS, 00442 MCP_TX_INTS, 00443 MCP_RX0IF, 00444 MCP_RX1IF, 00445 MCP_TX0IF, 00446 MCP_TX1IF, 00447 MCP_TX2IF, 00448 MCP_ERRIF, 00449 MCP_WAKIF, 00450 MCP_MERRF 00451 }; 00452 00453 mcpWrite(obj, MCP_CANINTE, which[irqSet]); 00454 } 00455 00456 /* Report on the specified interrupt causes 00457 */ 00458 uint8_t mcpInterruptType(mcp_can_t *obj, const CANIrqs irqFlag) 00459 { 00460 uint8_t which[] = { MCP_NO_INTS, 00461 MCP_ALL_INTS, 00462 MCP_RX_INTS, 00463 MCP_TX_INTS, 00464 MCP_RX0IF, 00465 MCP_RX1IF, 00466 MCP_TX0IF, 00467 MCP_TX1IF, 00468 MCP_TX2IF, 00469 MCP_ERRIF, 00470 MCP_WAKIF, 00471 MCP_MERRF 00472 }; 00473 00474 return (mcpRead(obj, MCP_EFLG) & which[irqFlag]) ? 1 : 0; 00475 } 00476 00477 /* Return contents of the interrupt flags register 00478 */ 00479 uint8_t mcpInterruptFlags(mcp_can_t *obj) 00480 { 00481 return (mcpRead(obj, MCP_EFLG)); 00482 }
Generated on Tue Jul 12 2022 19:07:56 by
1.7.2
