eeprom adding
Fork of SEEED_CAN by
Embed:
(wiki syntax)
Show/hide line numbers
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