Seed can implementation
Fork of SEEED_CAN by
seeed_can_api.cpp@4:5c9a071a4c07, 2017-03-10 (annotated)
- Committer:
- lightway
- Date:
- Fri Mar 10 06:26:20 2017 +0000
- Revision:
- 4:5c9a071a4c07
- Parent:
- 2:fd026fcfde94
Sample CAN message;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Just4pLeisure | 0:f5d099885d3d | 1 | /* seeed_can_api.cpp |
Just4pLeisure | 0:f5d099885d3d | 2 | * Copyright (c) 2013 Sophie Dexter |
Just4pLeisure | 0:f5d099885d3d | 3 | * |
Just4pLeisure | 0:f5d099885d3d | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
Just4pLeisure | 0:f5d099885d3d | 5 | * you may not use this file except in compliance with the License. |
Just4pLeisure | 0:f5d099885d3d | 6 | * You may obtain a copy of the License at |
Just4pLeisure | 0:f5d099885d3d | 7 | * |
Just4pLeisure | 0:f5d099885d3d | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
Just4pLeisure | 0:f5d099885d3d | 9 | * |
Just4pLeisure | 0:f5d099885d3d | 10 | * Unless required by applicable law or agreed to in writing, software |
Just4pLeisure | 0:f5d099885d3d | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
Just4pLeisure | 0:f5d099885d3d | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Just4pLeisure | 0:f5d099885d3d | 13 | * See the License for the specific language governing permissions and |
Just4pLeisure | 0:f5d099885d3d | 14 | * limitations under the License. |
Just4pLeisure | 0:f5d099885d3d | 15 | */ |
Just4pLeisure | 0:f5d099885d3d | 16 | |
Just4pLeisure | 0:f5d099885d3d | 17 | #include "seeed_can_api.h" |
Just4pLeisure | 0:f5d099885d3d | 18 | |
Just4pLeisure | 0:f5d099885d3d | 19 | /** Initialise the MCP2515 and set the bit rate |
Just4pLeisure | 0:f5d099885d3d | 20 | */ |
Just4pLeisure | 2:fd026fcfde94 | 21 | uint8_t mcpInit(mcp_can_t *obj, const uint32_t bitRate, const CANMode mode) |
Just4pLeisure | 0:f5d099885d3d | 22 | { |
Just4pLeisure | 0:f5d099885d3d | 23 | union { // Access CANMsg as: |
Just4pLeisure | 0:f5d099885d3d | 24 | CANMsg x; // the organised struct |
Just4pLeisure | 0:f5d099885d3d | 25 | uint8_t y[]; // or contiguous memory array |
Just4pLeisure | 0:f5d099885d3d | 26 | }; |
Just4pLeisure | 0:f5d099885d3d | 27 | uint8_t maskFilt[8] = { MCP_RXM0SIDH, MCP_RXM1SIDH, MCP_RXF0SIDH, MCP_RXF1SIDH, MCP_RXF2SIDH, MCP_RXF3SIDH, MCP_RXF4SIDH, MCP_RXF5SIDH }; |
Just4pLeisure | 0:f5d099885d3d | 28 | uint8_t canBufCtrl[5] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL, MCP_RXB0CTRL, MCP_RXB1CTRL }; |
Just4pLeisure | 0:f5d099885d3d | 29 | uint8_t canBuffer[3] = { MCP_TXB0CTRL+1, MCP_TXB1CTRL+1, MCP_TXB2CTRL+1 }; |
Just4pLeisure | 0:f5d099885d3d | 30 | |
Just4pLeisure | 0:f5d099885d3d | 31 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 32 | printf("Reseting MCP2515\r\n"); |
Just4pLeisure | 0:f5d099885d3d | 33 | #endif |
Just4pLeisure | 0:f5d099885d3d | 34 | mcpReset(obj); |
Just4pLeisure | 0:f5d099885d3d | 35 | for (uint32_t i = 0; i < 8; i++) { // Clear all CAN id masks and filters |
Just4pLeisure | 0:f5d099885d3d | 36 | mcpWriteId(obj, maskFilt[i], NULL, NULL); |
Just4pLeisure | 0:f5d099885d3d | 37 | } |
Just4pLeisure | 0:f5d099885d3d | 38 | for (uint32_t i = 0; i < 5; i++) { // Clear all CAN buffer control registers |
Just4pLeisure | 0:f5d099885d3d | 39 | mcpWrite(obj, canBufCtrl[i], NULL); |
Just4pLeisure | 0:f5d099885d3d | 40 | } |
Just4pLeisure | 0:f5d099885d3d | 41 | for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise empty CAN message buffer |
Just4pLeisure | 0:f5d099885d3d | 42 | for (uint32_t i = 0; i < 3; i++) { // Clear all CAN TX buffers |
Just4pLeisure | 0:f5d099885d3d | 43 | mcpWriteMultiple(obj, canBuffer[i], y, sizeof(x) ); // using empty CAN message (as an array) |
Just4pLeisure | 0:f5d099885d3d | 44 | } |
Just4pLeisure | 1:ad71faa09868 | 45 | // 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 |
Just4pLeisure | 0:f5d099885d3d | 46 | mcpBitModify(obj, MCP_RXB0CTRL, MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK, MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK ); |
Just4pLeisure | 0:f5d099885d3d | 47 | mcpBitModify(obj, MCP_RXB1CTRL, MCP_RXB_RX_MASK, MCP_RXB_RX_STDEXT); |
Just4pLeisure | 0:f5d099885d3d | 48 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 49 | printf("Setting bit rate\r\n"); |
Just4pLeisure | 0:f5d099885d3d | 50 | #endif |
Just4pLeisure | 1:ad71faa09868 | 51 | if (!mcpSetBitRate(obj, bitRate)) { // set baudrate |
Just4pLeisure | 1:ad71faa09868 | 52 | return 0; |
Just4pLeisure | 1:ad71faa09868 | 53 | } |
Just4pLeisure | 2:fd026fcfde94 | 54 | // return mcpSetMode(obj, MODE_NORMAL) ? 1 : 0; // set Normal mode and return |
Just4pLeisure | 2:fd026fcfde94 | 55 | return mcpSetMode(obj, mode) ? 1 : 0; // set Normal mode and return |
Just4pLeisure | 0:f5d099885d3d | 56 | } |
Just4pLeisure | 0:f5d099885d3d | 57 | |
Just4pLeisure | 0:f5d099885d3d | 58 | /** set MCP2515 operation mode |
Just4pLeisure | 0:f5d099885d3d | 59 | * |
Just4pLeisure | 0:f5d099885d3d | 60 | * Configuration, Normal, Sleep, Listen-only or Loopback |
Just4pLeisure | 0:f5d099885d3d | 61 | */ |
Just4pLeisure | 2:fd026fcfde94 | 62 | uint8_t mcpSetMode(mcp_can_t *obj, const uint8_t newmode) |
Just4pLeisure | 0:f5d099885d3d | 63 | { |
Just4pLeisure | 0:f5d099885d3d | 64 | mcpBitModify(obj, MCP_CANCTRL, MODE_MASK, newmode); |
Just4pLeisure | 0:f5d099885d3d | 65 | for (uint32_t i = 0; i<10; i++) { |
Just4pLeisure | 0:f5d099885d3d | 66 | if ((mcpRead(obj, MCP_CANSTAT) & MODE_MASK) == newmode) { |
Just4pLeisure | 0:f5d099885d3d | 67 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 68 | printf("Successfully entered mode: %02x time: %dms\r\n", newmode, i); |
Just4pLeisure | 0:f5d099885d3d | 69 | 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)); |
Just4pLeisure | 0:f5d099885d3d | 70 | #endif |
Just4pLeisure | 0:f5d099885d3d | 71 | return 1; |
Just4pLeisure | 0:f5d099885d3d | 72 | } |
Just4pLeisure | 0:f5d099885d3d | 73 | wait_ms(1); |
Just4pLeisure | 0:f5d099885d3d | 74 | } |
Just4pLeisure | 0:f5d099885d3d | 75 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 76 | printf("Failed to enter mode: %02x\r\n", newmode); |
Just4pLeisure | 0:f5d099885d3d | 77 | 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)); |
Just4pLeisure | 0:f5d099885d3d | 78 | #endif |
Just4pLeisure | 0:f5d099885d3d | 79 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 80 | } |
Just4pLeisure | 0:f5d099885d3d | 81 | |
Just4pLeisure | 0:f5d099885d3d | 82 | /** set the CAN bus bitrate |
Just4pLeisure | 0:f5d099885d3d | 83 | * |
Just4pLeisure | 0:f5d099885d3d | 84 | * Calculate suitable BTR register values. |
Just4pLeisure | 0:f5d099885d3d | 85 | * The Bit Rate Pre-scaler (BRP) can be in the range of 1-64. |
Just4pLeisure | 0:f5d099885d3d | 86 | * According to CANopen, Bit Time can be be between 25 and 8 Time Quanta (TQU). |
Just4pLeisure | 0:f5d099885d3d | 87 | * Bit Time = SyncSeg(1 TQU) + PropSeg(1-8 TQU) + PhaseSeg1(1-8 TQU) + PhaseSeg2(2-8 TQU). |
Just4pLeisure | 0:f5d099885d3d | 88 | * SyncSeg is always 1TQU, PhaseSeg2 must be at least 2TQU to be longer than the processing time. |
Just4pLeisure | 0:f5d099885d3d | 89 | * Opinions vary on when to take a sample but a point roughly 2/3 of Bit Time seems OK. |
Just4pLeisure | 0:f5d099885d3d | 90 | * Synchronisation Jump width can be 1-4 TQU, a value of 1 seems to be normal. |
Just4pLeisure | 0:f5d099885d3d | 91 | * |
Just4pLeisure | 0:f5d099885d3d | 92 | * All register values are -1, e.g. PropSeg can range from 1-8 TQU, so values are 0-7 (0-63 for BRP). |
Just4pLeisure | 0:f5d099885d3d | 93 | * |
Just4pLeisure | 0:f5d099885d3d | 94 | * This table has the sampling points as close to 2/3 (66.7%) as possible. |
Just4pLeisure | 0:f5d099885d3d | 95 | * The first value is PropSeg, 2nd PhaseSeg1. |
Just4pLeisure | 0:f5d099885d3d | 96 | * PhaseSeg2 will be the same as PhaseSeg1 when btlmode bit is initialised to 0. |
Just4pLeisure | 0:f5d099885d3d | 97 | */ |
Just4pLeisure | 0:f5d099885d3d | 98 | static const uint8_t timing_pts[18][2] = { |
Just4pLeisure | 0:f5d099885d3d | 99 | {0x0, 0x2}, // 8, 62.5% |
Just4pLeisure | 0:f5d099885d3d | 100 | {0x1, 0x2}, // 9, 66.7% |
Just4pLeisure | 0:f5d099885d3d | 101 | {0x2, 0x2}, // 10, 70.0% |
Just4pLeisure | 0:f5d099885d3d | 102 | {0x1, 0x3}, // 11, 63.6% |
Just4pLeisure | 0:f5d099885d3d | 103 | {0x2, 0x3}, // 12, 66.7% |
Just4pLeisure | 0:f5d099885d3d | 104 | {0x3, 0x3}, // 13, 69.2% |
Just4pLeisure | 0:f5d099885d3d | 105 | {0x2, 0x4}, // 14, 64.3% |
Just4pLeisure | 0:f5d099885d3d | 106 | {0x3, 0x4}, // 15, 66.7% |
Just4pLeisure | 0:f5d099885d3d | 107 | {0x4, 0x4}, // 16, 68.75% |
Just4pLeisure | 0:f5d099885d3d | 108 | {0x3, 0x5}, // 17, 64.7% |
Just4pLeisure | 0:f5d099885d3d | 109 | {0x4, 0x5}, // 18, 66.7% |
Just4pLeisure | 0:f5d099885d3d | 110 | {0x5, 0x5}, // 19, 63.2% |
Just4pLeisure | 0:f5d099885d3d | 111 | {0x4, 0x6}, // 20, 65.0% |
Just4pLeisure | 0:f5d099885d3d | 112 | {0x5, 0x6}, // 21, 66.7% |
Just4pLeisure | 0:f5d099885d3d | 113 | {0x6, 0x6}, // 22, 68.2% |
Just4pLeisure | 0:f5d099885d3d | 114 | {0x5, 0x7}, // 23, 65.2 |
Just4pLeisure | 0:f5d099885d3d | 115 | {0x6, 0x7}, // 24, 66.7% |
Just4pLeisure | 0:f5d099885d3d | 116 | {0x7, 0x7}, // 25, 68.0% |
Just4pLeisure | 0:f5d099885d3d | 117 | }; |
Just4pLeisure | 0:f5d099885d3d | 118 | |
Just4pLeisure | 2:fd026fcfde94 | 119 | uint8_t mcpSetBitRate(mcp_can_t *obj, const uint32_t bitRate) |
Just4pLeisure | 0:f5d099885d3d | 120 | { |
Just4pLeisure | 0:f5d099885d3d | 121 | union { // Access CANtiming as: |
Just4pLeisure | 0:f5d099885d3d | 122 | CANtiming x; // the organised struct |
Just4pLeisure | 0:f5d099885d3d | 123 | uint8_t y[]; // or contiguous memory array |
Just4pLeisure | 0:f5d099885d3d | 124 | }; |
Just4pLeisure | 0:f5d099885d3d | 125 | uint32_t bestBRP = 0; |
Just4pLeisure | 0:f5d099885d3d | 126 | uint32_t bestTQU = 0; |
Just4pLeisure | 0:f5d099885d3d | 127 | uint32_t bestCanRate = 0; |
Just4pLeisure | 0:f5d099885d3d | 128 | uint32_t minBRP = (MCP_CLOCK_FREQ / (2 * MCP_MAX_TIME_QUANTA * bitRate)); |
Just4pLeisure | 0:f5d099885d3d | 129 | uint32_t maxBRP = (MCP_CLOCK_FREQ / (2 * MCP_MIN_TIME_QUANTA * bitRate)); |
Just4pLeisure | 1:ad71faa09868 | 130 | |
Just4pLeisure | 1:ad71faa09868 | 131 | #ifdef DEBUG |
Just4pLeisure | 1:ad71faa09868 | 132 | printf("Setting configuration mode\r\n"); |
Just4pLeisure | 1:ad71faa09868 | 133 | #endif |
Just4pLeisure | 1:ad71faa09868 | 134 | uint8_t initialMode = mcpRead(obj, MCP_CANCTRL) & MODE_MASK; // Store the current operation mode |
Just4pLeisure | 1:ad71faa09868 | 135 | if(!mcpSetMode(obj, MODE_CONFIG)) { // Go into configuration mode |
Just4pLeisure | 1:ad71faa09868 | 136 | return 0; |
Just4pLeisure | 1:ad71faa09868 | 137 | } |
Just4pLeisure | 1:ad71faa09868 | 138 | |
Just4pLeisure | 0:f5d099885d3d | 139 | for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise CANtiming (btlmode, sjw and sam all = 0) |
Just4pLeisure | 0:f5d099885d3d | 140 | if ((bitRate < CAN_MIN_RATE) || (bitRate > CAN_MAX_RATE)) { |
Just4pLeisure | 0:f5d099885d3d | 141 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 142 | printf("FAILED!! The requested Bit Rate is too high or too low: %d\r\n", bitRate); |
Just4pLeisure | 0:f5d099885d3d | 143 | #endif |
Just4pLeisure | 0:f5d099885d3d | 144 | return 0; // Cannot set the requested bit rate! |
Just4pLeisure | 0:f5d099885d3d | 145 | } |
Just4pLeisure | 0:f5d099885d3d | 146 | minBRP = (minBRP == 0) ? MCP_MIN_PRESCALER : minBRP; |
Just4pLeisure | 0:f5d099885d3d | 147 | maxBRP = (maxBRP > MCP_MAX_PRESCALER) ? MCP_MAX_PRESCALER : maxBRP; |
Just4pLeisure | 0:f5d099885d3d | 148 | for (uint32_t BRP = minBRP; BRP < (maxBRP + 1); BRP++) { |
Just4pLeisure | 0:f5d099885d3d | 149 | uint32_t timeQuanta = (MCP_CLOCK_FREQ / (2 * BRP * bitRate)); |
Just4pLeisure | 0:f5d099885d3d | 150 | if ((timeQuanta >= MCP_MIN_TIME_QUANTA) && (timeQuanta <= MCP_MAX_TIME_QUANTA)) { |
Just4pLeisure | 0:f5d099885d3d | 151 | for (uint32_t TQU = timeQuanta; TQU <= MCP_MAX_TIME_QUANTA; TQU++) { |
Just4pLeisure | 0:f5d099885d3d | 152 | uint32_t thisCanRate = MCP_CLOCK_FREQ / (2 * BRP * TQU); |
Just4pLeisure | 0:f5d099885d3d | 153 | if ( abs((int)bitRate - (int)thisCanRate) < abs((int)bitRate - (int)bestCanRate)) { |
Just4pLeisure | 0:f5d099885d3d | 154 | bestCanRate = thisCanRate; |
Just4pLeisure | 0:f5d099885d3d | 155 | bestBRP= BRP; |
Just4pLeisure | 0:f5d099885d3d | 156 | bestTQU= TQU; |
Just4pLeisure | 0:f5d099885d3d | 157 | } |
Just4pLeisure | 0:f5d099885d3d | 158 | } |
Just4pLeisure | 0:f5d099885d3d | 159 | } |
Just4pLeisure | 0:f5d099885d3d | 160 | } |
Just4pLeisure | 0:f5d099885d3d | 161 | x.brp = (bestBRP - 1); |
Just4pLeisure | 0:f5d099885d3d | 162 | x.prseg = (timing_pts[bestTQU - 8][0]); |
Just4pLeisure | 0:f5d099885d3d | 163 | x.phseg1 = (timing_pts[bestTQU - 8][1]); |
Just4pLeisure | 0:f5d099885d3d | 164 | mcpWriteMultiple(obj, MCP_CNF3, y, sizeof(x) ); // Copy CANtiming to the MCP2515 (as an array) |
Just4pLeisure | 0:f5d099885d3d | 165 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 166 | printf("minBRP %d maxBRP %d\r\n", minBRP, maxBRP); |
Just4pLeisure | 0:f5d099885d3d | 167 | printf("Bitrate: %d\tactualBitRate: %d\t Error: %1.2f percent.\r\n", bitRate, bestCanRate, (100-(100*(float)bitRate/(float)bestCanRate))); |
Just4pLeisure | 0:f5d099885d3d | 168 | printf("TimeQuanta: %d\tbitRatePrescaler: %d\tSamplePoint: %2.2f percent\r\n", bestTQU, bestBRP, 100*(float)(3 + x.prseg + x.phseg1)/(float)bestTQU ) ; |
Just4pLeisure | 0:f5d099885d3d | 169 | printf("Syncseg: 1\tPropSeg: %d\tPhaseSeg1: %d\tPhaseSeg2: %d\r\n", (x.prseg+1), (x.phseg1+1), (x.phseg1+1)); |
Just4pLeisure | 0:f5d099885d3d | 170 | printf("Setting normal mode\r\n"); |
Just4pLeisure | 0:f5d099885d3d | 171 | #endif |
Just4pLeisure | 1:ad71faa09868 | 172 | return (mcpSetMode(obj, initialMode)) ? 1 : 0; // desired bit rate set enter normal mode and return |
Just4pLeisure | 0:f5d099885d3d | 173 | } |
Just4pLeisure | 0:f5d099885d3d | 174 | |
Just4pLeisure | 0:f5d099885d3d | 175 | /** write a CAN id to a mask, filter or transmit buffer |
Just4pLeisure | 0:f5d099885d3d | 176 | */ |
Just4pLeisure | 2:fd026fcfde94 | 177 | void mcpWriteId(mcp_can_t *obj, const uint8_t mcp_addr, const uint8_t ext, const uint32_t id ) |
Just4pLeisure | 0:f5d099885d3d | 178 | { |
Just4pLeisure | 0:f5d099885d3d | 179 | union { // Access CANid as: |
Just4pLeisure | 0:f5d099885d3d | 180 | CANid x; // the organised struct |
Just4pLeisure | 0:f5d099885d3d | 181 | uint8_t y[]; // or contiguous memory array |
Just4pLeisure | 0:f5d099885d3d | 182 | }; |
Just4pLeisure | 0:f5d099885d3d | 183 | |
Just4pLeisure | 0:f5d099885d3d | 184 | for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise CANid structure |
Just4pLeisure | 0:f5d099885d3d | 185 | x.ide = ext; // Extended Identifier Flag |
Just4pLeisure | 0:f5d099885d3d | 186 | if (x.ide == CANExtended) { |
Just4pLeisure | 0:f5d099885d3d | 187 | x.sid10_3 = (uint8_t) (id >> 21); // SID10..3 |
Just4pLeisure | 0:f5d099885d3d | 188 | x.sid2_0 = (uint8_t) (id >> 18) & 0x07; // SID2..0 |
Just4pLeisure | 0:f5d099885d3d | 189 | x.eid17_16 = (uint8_t) (id >> 16) & 0x03; // EID17..16 |
Just4pLeisure | 0:f5d099885d3d | 190 | x.eid15_8 = (uint8_t) (id >> 8); // EID15..8 |
Just4pLeisure | 0:f5d099885d3d | 191 | x.eid7_0 = (uint8_t) id; // EID7..0 |
Just4pLeisure | 0:f5d099885d3d | 192 | } else { |
Just4pLeisure | 0:f5d099885d3d | 193 | x.sid10_3 = (uint8_t) (id >> 3); // SID10..3 |
Just4pLeisure | 0:f5d099885d3d | 194 | x.sid2_0 = (uint8_t) (id & 0x07); // SID2..0 |
Just4pLeisure | 0:f5d099885d3d | 195 | } |
Just4pLeisure | 0:f5d099885d3d | 196 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 197 | printf("sizeof CanIdStruct: %d bytes\r\n", sizeof(x)); |
Just4pLeisure | 0:f5d099885d3d | 198 | printf("sid10_3: %x\r\n", x.sid10_3); |
Just4pLeisure | 0:f5d099885d3d | 199 | printf("eid17_16: %x\r\n", x.eid17_16); |
Just4pLeisure | 0:f5d099885d3d | 200 | printf("ide: %x\r\n", x.ide); |
Just4pLeisure | 0:f5d099885d3d | 201 | printf("srtr: %x\r\n", x.srtr); |
Just4pLeisure | 0:f5d099885d3d | 202 | printf("sid2_0: %x\r\n", x.sid2_0); |
Just4pLeisure | 0:f5d099885d3d | 203 | printf("eid15_8: %x\r\n", x.eid15_8); |
Just4pLeisure | 0:f5d099885d3d | 204 | printf("eid7_0: %x\r\n", x.eid7_0); |
Just4pLeisure | 0:f5d099885d3d | 205 | #endif |
Just4pLeisure | 0:f5d099885d3d | 206 | mcpWriteMultiple(obj, mcp_addr, y, sizeof(x) ); // Copy CANid to the MCP2515 (as an array) |
Just4pLeisure | 0:f5d099885d3d | 207 | } |
Just4pLeisure | 0:f5d099885d3d | 208 | |
Just4pLeisure | 0:f5d099885d3d | 209 | /** write a CAN message to the MCP2515 |
Just4pLeisure | 0:f5d099885d3d | 210 | */ |
Just4pLeisure | 2:fd026fcfde94 | 211 | uint8_t mcpCanWrite(mcp_can_t *obj, CAN_Message msg) |
Just4pLeisure | 0:f5d099885d3d | 212 | { |
Just4pLeisure | 0:f5d099885d3d | 213 | union { // Access CANMsg as: |
Just4pLeisure | 0:f5d099885d3d | 214 | CANMsg x; // the organised struct |
Just4pLeisure | 0:f5d099885d3d | 215 | uint8_t y[]; // or contiguous memory array |
Just4pLeisure | 0:f5d099885d3d | 216 | }; |
Just4pLeisure | 0:f5d099885d3d | 217 | uint8_t bufferCommand[] = {MCP_WRITE_TX0, MCP_WRITE_TX1, MCP_WRITE_TX2}; |
Just4pLeisure | 0:f5d099885d3d | 218 | uint8_t rtsCommand[] = {MCP_RTS_TX0, MCP_RTS_TX1, MCP_RTS_TX2}; |
Just4pLeisure | 0:f5d099885d3d | 219 | uint8_t status = mcpStatus(obj); |
Just4pLeisure | 0:f5d099885d3d | 220 | uint32_t num = 0; |
Just4pLeisure | 0:f5d099885d3d | 221 | // Check if there is a free message buffer |
Just4pLeisure | 0:f5d099885d3d | 222 | if (!(status & MCP_STAT_TX0REQ)) { // TX Message Buffer 0 free? |
Just4pLeisure | 0:f5d099885d3d | 223 | num = 0; |
Just4pLeisure | 0:f5d099885d3d | 224 | } else if (!(status & MCP_STAT_TX1REQ)) { // TX Message Buffer 1 free? |
Just4pLeisure | 0:f5d099885d3d | 225 | num = 1; |
Just4pLeisure | 0:f5d099885d3d | 226 | } else if (!(status & MCP_STAT_TX2REQ)) { // TX Message Buffer 2 free? |
Just4pLeisure | 0:f5d099885d3d | 227 | num = 2; |
Just4pLeisure | 0:f5d099885d3d | 228 | } else { |
Just4pLeisure | 0:f5d099885d3d | 229 | return 0; // No free transmit buffers in the MCP2515 CAN controller chip |
Just4pLeisure | 0:f5d099885d3d | 230 | } |
Just4pLeisure | 0:f5d099885d3d | 231 | // populate CANMsg structure |
Just4pLeisure | 0:f5d099885d3d | 232 | for (uint32_t i = 0; i < sizeof(x); i++) y[i] = NULL; // Initialise CANMsg structure |
Just4pLeisure | 0:f5d099885d3d | 233 | x.id.ide = msg.format; // Extended Identifier Flag |
Just4pLeisure | 0:f5d099885d3d | 234 | if (x.id.ide == CANExtended) { |
Just4pLeisure | 0:f5d099885d3d | 235 | x.id.sid10_3 = (uint8_t) (msg.id >> 21); // SID10..3 |
Just4pLeisure | 0:f5d099885d3d | 236 | x.id.sid2_0 = (uint8_t) (msg.id >> 18) & 0x07; // SID2..0 |
Just4pLeisure | 0:f5d099885d3d | 237 | x.id.eid17_16 = (uint8_t) (msg.id >> 16) & 0x03; // EID17..16 |
Just4pLeisure | 0:f5d099885d3d | 238 | x.id.eid15_8 = (uint8_t) (msg.id >> 8); // EID15..8 |
Just4pLeisure | 0:f5d099885d3d | 239 | x.id.eid7_0 = (uint8_t) msg.id; // EID7..0 |
Just4pLeisure | 0:f5d099885d3d | 240 | } else { |
Just4pLeisure | 0:f5d099885d3d | 241 | x.id.sid10_3 = (uint8_t) (msg.id >> 3); // SID10..3 |
Just4pLeisure | 0:f5d099885d3d | 242 | x.id.sid2_0 = (uint8_t) (msg.id & 0x07); // SID2..0 |
Just4pLeisure | 0:f5d099885d3d | 243 | } |
Just4pLeisure | 0:f5d099885d3d | 244 | x.dlc = msg.len & 0x0f; // Number of bytes in can message |
Just4pLeisure | 0:f5d099885d3d | 245 | x.ertr = msg.type; // Data or remote message |
Just4pLeisure | 0:f5d099885d3d | 246 | memcpy(x.data,msg.data,x.dlc); // Get the Data bytes |
Just4pLeisure | 0:f5d099885d3d | 247 | // write CANmsg to the specified TX buffer 'num' |
Just4pLeisure | 0:f5d099885d3d | 248 | mcpWriteBuffer(obj, bufferCommand[num], y, sizeof(x)); // Write the message ,CANMsg, to the MCP2515's Tx buffer 'num' (as an array) |
Just4pLeisure | 0:f5d099885d3d | 249 | mcpBufferRTS(obj, rtsCommand[num]); |
Just4pLeisure | 0:f5d099885d3d | 250 | return 1; // Indicate that message has been transmitted |
Just4pLeisure | 0:f5d099885d3d | 251 | } |
Just4pLeisure | 0:f5d099885d3d | 252 | |
Just4pLeisure | 0:f5d099885d3d | 253 | /** read a CAN message from the MCP2515 |
Just4pLeisure | 0:f5d099885d3d | 254 | */ |
Just4pLeisure | 2:fd026fcfde94 | 255 | uint8_t mcpCanRead(mcp_can_t *obj, CAN_Message *msg) |
Just4pLeisure | 0:f5d099885d3d | 256 | { |
Just4pLeisure | 0:f5d099885d3d | 257 | union { // Access CANMsg as: |
Just4pLeisure | 0:f5d099885d3d | 258 | CANMsg x; // the organised struct |
Just4pLeisure | 0:f5d099885d3d | 259 | uint8_t y[]; // or contiguous memory array |
Just4pLeisure | 0:f5d099885d3d | 260 | }; |
Just4pLeisure | 0:f5d099885d3d | 261 | uint8_t bufferCommand[] = {MCP_READ_RX0, MCP_READ_RX1}; |
Just4pLeisure | 0:f5d099885d3d | 262 | uint8_t status = mcpReceiveStatus(obj); |
Just4pLeisure | 0:f5d099885d3d | 263 | bool num = 0; |
Just4pLeisure | 0:f5d099885d3d | 264 | // Check if there is a message the buffers |
Just4pLeisure | 0:f5d099885d3d | 265 | if (status & MCP_RXSTAT_RXB0) { // Msg in Buffer 0? |
Just4pLeisure | 0:f5d099885d3d | 266 | num = 0; |
Just4pLeisure | 0:f5d099885d3d | 267 | } else if (status & MCP_RXSTAT_RXB1) { // Msg in Buffer 1? |
Just4pLeisure | 0:f5d099885d3d | 268 | num = 1; |
Just4pLeisure | 0:f5d099885d3d | 269 | } else { |
Just4pLeisure | 0:f5d099885d3d | 270 | return 0; // No messages waiting |
Just4pLeisure | 0:f5d099885d3d | 271 | } |
Just4pLeisure | 0:f5d099885d3d | 272 | mcpReadBuffer(obj, bufferCommand[0], y, sizeof(x)); // Read the message into CANMsg (as an array) |
Just4pLeisure | 0:f5d099885d3d | 273 | mcpBitModify(obj, MCP_CANINTF, (!num ? MCP_RX0IF : MCP_RX1IF), 0); // Free the message buffer |
Just4pLeisure | 0:f5d099885d3d | 274 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 275 | printf("sizeof CanMsgStruct: %d bytes\r\n", sizeof(x)); |
Just4pLeisure | 0:f5d099885d3d | 276 | printf("sizeof CanMsgArray: %d bytes\r\n", sizeof(y)); |
Just4pLeisure | 0:f5d099885d3d | 277 | printf("sid10_3: %x\r\n", x.id.sid10_3); |
Just4pLeisure | 0:f5d099885d3d | 278 | printf("eid17_16: %x\r\n", x.id.eid17_16); |
Just4pLeisure | 0:f5d099885d3d | 279 | printf("ide: %x\r\n", x.id.ide); |
Just4pLeisure | 0:f5d099885d3d | 280 | printf("srtr: %x\r\n", x.id.srtr); |
Just4pLeisure | 0:f5d099885d3d | 281 | printf("sid2_0: %x\r\n", x.id.sid2_0); |
Just4pLeisure | 0:f5d099885d3d | 282 | printf("eid15_8: %x\r\n", x.id.eid15_8); |
Just4pLeisure | 0:f5d099885d3d | 283 | printf("eid7_0: %x\r\n", x.id.eid7_0); |
Just4pLeisure | 0:f5d099885d3d | 284 | printf("dlc: %x\r\n", x.dlc); |
Just4pLeisure | 0:f5d099885d3d | 285 | printf("ertr: %x\r\n", x.ertr); |
Just4pLeisure | 0:f5d099885d3d | 286 | printf("data: "); |
Just4pLeisure | 0:f5d099885d3d | 287 | for (char i=0; i<8; i++) |
Just4pLeisure | 0:f5d099885d3d | 288 | printf("%02x,", x.data[i]); |
Just4pLeisure | 0:f5d099885d3d | 289 | printf("\r\n"); |
Just4pLeisure | 0:f5d099885d3d | 290 | #endif |
Just4pLeisure | 0:f5d099885d3d | 291 | msg->format = (status & MCP_RXSTAT_IDE) ? CANExtended : CANStandard;// Extended CAN id Flag |
Just4pLeisure | 0:f5d099885d3d | 292 | if (msg->format == CANExtended) { // Assemble the Extended CAN id |
Just4pLeisure | 0:f5d099885d3d | 293 | msg->id = (x.id.sid10_3 << 21) | |
Just4pLeisure | 0:f5d099885d3d | 294 | (x.id.sid2_0 << 18) | |
Just4pLeisure | 0:f5d099885d3d | 295 | (x.id.eid17_16 << 16) | |
Just4pLeisure | 0:f5d099885d3d | 296 | (x.id.eid15_8 << 8) | |
Just4pLeisure | 0:f5d099885d3d | 297 | (x.id.eid7_0); |
Just4pLeisure | 0:f5d099885d3d | 298 | } else { // Assemble the Standard CAN id |
Just4pLeisure | 0:f5d099885d3d | 299 | msg->id = (x.id.sid10_3 << 3) | |
Just4pLeisure | 0:f5d099885d3d | 300 | (x.id.sid2_0); |
Just4pLeisure | 0:f5d099885d3d | 301 | } |
Just4pLeisure | 0:f5d099885d3d | 302 | msg->len = x.dlc; // Number of bytes in CAN message |
Just4pLeisure | 0:f5d099885d3d | 303 | msg->type = (status & MCP_RXSTAT_RTR) ? CANRemote : CANData; // Determine if a Remote or Data message type |
Just4pLeisure | 0:f5d099885d3d | 304 | memcpy(msg->data,x.data,x.dlc); // Get the Data bytes |
Just4pLeisure | 0:f5d099885d3d | 305 | return 1; // Indicate that message has been retrieved |
Just4pLeisure | 0:f5d099885d3d | 306 | } |
Just4pLeisure | 0:f5d099885d3d | 307 | |
Just4pLeisure | 0:f5d099885d3d | 308 | /** initialise an Acceptance Mask |
Just4pLeisure | 0:f5d099885d3d | 309 | */ |
Just4pLeisure | 2:fd026fcfde94 | 310 | uint8_t mcpInitMask(mcp_can_t *obj, uint8_t num, uint32_t ulData, bool ext) |
Just4pLeisure | 0:f5d099885d3d | 311 | { |
Just4pLeisure | 0:f5d099885d3d | 312 | uint8_t mask[2] = { MCP_RXM0SIDH, MCP_RXM1SIDH }; |
Just4pLeisure | 0:f5d099885d3d | 313 | |
Just4pLeisure | 0:f5d099885d3d | 314 | if (num > 1) { |
Just4pLeisure | 0:f5d099885d3d | 315 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 316 | printf("Trying to set an invalid Mask number: %d\r\n", num); |
Just4pLeisure | 0:f5d099885d3d | 317 | #endif |
Just4pLeisure | 0:f5d099885d3d | 318 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 319 | } |
Just4pLeisure | 0:f5d099885d3d | 320 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 321 | printf("Begin to set Mask!!\r\n"); |
Just4pLeisure | 0:f5d099885d3d | 322 | #endif |
Just4pLeisure | 1:ad71faa09868 | 323 | uint8_t initialMode = mcpRead(obj, MCP_CANCTRL) & MODE_MASK; // Store the current operation mode |
Just4pLeisure | 0:f5d099885d3d | 324 | if(!mcpSetMode(obj, MODE_CONFIG)) { |
Just4pLeisure | 0:f5d099885d3d | 325 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 326 | } |
Just4pLeisure | 0:f5d099885d3d | 327 | mcpWriteId(obj, mask[num], ext, ulData); |
Just4pLeisure | 1:ad71faa09868 | 328 | if(!mcpSetMode(obj, initialMode)) { |
Just4pLeisure | 0:f5d099885d3d | 329 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 330 | } |
Just4pLeisure | 0:f5d099885d3d | 331 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 332 | printf("Successfully set Mask number: %d\r\n", num); |
Just4pLeisure | 0:f5d099885d3d | 333 | #endif |
Just4pLeisure | 0:f5d099885d3d | 334 | return 1; |
Just4pLeisure | 0:f5d099885d3d | 335 | } |
Just4pLeisure | 0:f5d099885d3d | 336 | |
Just4pLeisure | 0:f5d099885d3d | 337 | /** initialise an Acceptance Filter |
Just4pLeisure | 0:f5d099885d3d | 338 | */ |
Just4pLeisure | 2:fd026fcfde94 | 339 | uint8_t mcpInitFilter(mcp_can_t *obj, uint8_t num, uint32_t ulData, bool ext) |
Just4pLeisure | 0:f5d099885d3d | 340 | { |
Just4pLeisure | 0:f5d099885d3d | 341 | uint8_t filter[6] = { MCP_RXF0SIDH, MCP_RXF1SIDH, MCP_RXF2SIDH, MCP_RXF3SIDH, MCP_RXF4SIDH, MCP_RXF5SIDH }; |
Just4pLeisure | 0:f5d099885d3d | 342 | |
Just4pLeisure | 0:f5d099885d3d | 343 | if (num > 5) { |
Just4pLeisure | 0:f5d099885d3d | 344 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 345 | printf("Trying to set an invalid Filter number: %d\r\n", num); |
Just4pLeisure | 0:f5d099885d3d | 346 | #endif |
Just4pLeisure | 0:f5d099885d3d | 347 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 348 | } |
Just4pLeisure | 0:f5d099885d3d | 349 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 350 | printf("Begin to set Filter!!\r\n"); |
Just4pLeisure | 0:f5d099885d3d | 351 | #endif |
Just4pLeisure | 1:ad71faa09868 | 352 | uint8_t initialMode = mcpRead(obj, MCP_CANCTRL) & MODE_MASK; // Store the current operation mode |
Just4pLeisure | 0:f5d099885d3d | 353 | if(!mcpSetMode(obj, MODE_CONFIG)) { |
Just4pLeisure | 0:f5d099885d3d | 354 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 355 | } |
Just4pLeisure | 0:f5d099885d3d | 356 | mcpWriteId(obj, filter[num], ext, ulData); |
Just4pLeisure | 1:ad71faa09868 | 357 | if(!mcpSetMode(obj, initialMode)) { |
Just4pLeisure | 0:f5d099885d3d | 358 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 359 | } |
Just4pLeisure | 0:f5d099885d3d | 360 | #ifdef DEBUG |
Just4pLeisure | 0:f5d099885d3d | 361 | printf("Successfully set Filter: %d\r\n", num); |
Just4pLeisure | 0:f5d099885d3d | 362 | #endif |
Just4pLeisure | 0:f5d099885d3d | 363 | return 1; |
Just4pLeisure | 0:f5d099885d3d | 364 | } |
Just4pLeisure | 0:f5d099885d3d | 365 | |
Just4pLeisure | 2:fd026fcfde94 | 366 | /* Report on the specified errors and warnings |
Just4pLeisure | 2:fd026fcfde94 | 367 | */ |
Just4pLeisure | 2:fd026fcfde94 | 368 | uint8_t mcpErrorType(mcp_can_t *obj, const CANFlags type) |
Just4pLeisure | 2:fd026fcfde94 | 369 | { |
Just4pLeisure | 2:fd026fcfde94 | 370 | uint8_t which[] = { MCP_EFLG_ALLMASK, |
Just4pLeisure | 2:fd026fcfde94 | 371 | MCP_EFLG_ERRORMASK, |
Just4pLeisure | 2:fd026fcfde94 | 372 | MCP_EFLG_WARNMASK, |
Just4pLeisure | 2:fd026fcfde94 | 373 | MCP_EFLG_RX1OVR, |
Just4pLeisure | 2:fd026fcfde94 | 374 | MCP_EFLG_RX0OVR, |
Just4pLeisure | 2:fd026fcfde94 | 375 | MCP_EFLG_TXBO, |
Just4pLeisure | 2:fd026fcfde94 | 376 | MCP_EFLG_TXEP, |
Just4pLeisure | 2:fd026fcfde94 | 377 | MCP_EFLG_RXEP, |
Just4pLeisure | 2:fd026fcfde94 | 378 | MCP_EFLG_TXWAR, |
Just4pLeisure | 2:fd026fcfde94 | 379 | MCP_EFLG_RXWAR, |
Just4pLeisure | 2:fd026fcfde94 | 380 | MCP_EFLG_EWARN |
Just4pLeisure | 2:fd026fcfde94 | 381 | }; |
Just4pLeisure | 2:fd026fcfde94 | 382 | |
Just4pLeisure | 2:fd026fcfde94 | 383 | return (mcpRead(obj, MCP_EFLG) & which[type]) ? 1 : 0; |
Just4pLeisure | 2:fd026fcfde94 | 384 | } |
Just4pLeisure | 2:fd026fcfde94 | 385 | |
Just4pLeisure | 2:fd026fcfde94 | 386 | /* Return contents of the error and warning flags register |
Just4pLeisure | 2:fd026fcfde94 | 387 | */ |
Just4pLeisure | 2:fd026fcfde94 | 388 | uint8_t mcpErrorFlags(mcp_can_t *obj) |
Just4pLeisure | 2:fd026fcfde94 | 389 | { |
Just4pLeisure | 2:fd026fcfde94 | 390 | return (mcpRead(obj, MCP_EFLG)); |
Just4pLeisure | 2:fd026fcfde94 | 391 | } |
Just4pLeisure | 2:fd026fcfde94 | 392 | |
Just4pLeisure | 0:f5d099885d3d | 393 | /* Number of message reception errors |
Just4pLeisure | 0:f5d099885d3d | 394 | */ |
Just4pLeisure | 2:fd026fcfde94 | 395 | uint8_t mcpReceptionErrorCount(mcp_can_t *obj) |
Just4pLeisure | 0:f5d099885d3d | 396 | { |
Just4pLeisure | 0:f5d099885d3d | 397 | return (mcpRead(obj, MCP_REC)); |
Just4pLeisure | 0:f5d099885d3d | 398 | } |
Just4pLeisure | 0:f5d099885d3d | 399 | |
Just4pLeisure | 0:f5d099885d3d | 400 | /* Number of message transmission errors |
Just4pLeisure | 0:f5d099885d3d | 401 | */ |
Just4pLeisure | 2:fd026fcfde94 | 402 | uint8_t mcpTransmissionErrorCount(mcp_can_t *obj) |
Just4pLeisure | 0:f5d099885d3d | 403 | { |
Just4pLeisure | 0:f5d099885d3d | 404 | return (mcpRead(obj, MCP_TEC)); |
Just4pLeisure | 0:f5d099885d3d | 405 | } |
Just4pLeisure | 0:f5d099885d3d | 406 | |
Just4pLeisure | 0:f5d099885d3d | 407 | /* Select between monitor (silent = 1) and normal (silent = 0) modes |
Just4pLeisure | 0:f5d099885d3d | 408 | */ |
Just4pLeisure | 2:fd026fcfde94 | 409 | void mcpMonitor(mcp_can_t *obj, const bool silent) |
Just4pLeisure | 0:f5d099885d3d | 410 | { |
Just4pLeisure | 0:f5d099885d3d | 411 | silent ? mcpSetMode(obj, MODE_LISTENONLY) : mcpSetMode(obj, MODE_NORMAL); |
Just4pLeisure | 0:f5d099885d3d | 412 | } |
Just4pLeisure | 0:f5d099885d3d | 413 | |
Just4pLeisure | 0:f5d099885d3d | 414 | /* Change CAN operation to the specified mode |
Just4pLeisure | 0:f5d099885d3d | 415 | */ |
Just4pLeisure | 2:fd026fcfde94 | 416 | uint8_t mcpMode(mcp_can_t *obj, const CANMode mode) |
Just4pLeisure | 0:f5d099885d3d | 417 | { |
Just4pLeisure | 2:fd026fcfde94 | 418 | uint8_t which[] = { MODE_NORMAL, |
Just4pLeisure | 2:fd026fcfde94 | 419 | MODE_SLEEP, |
Just4pLeisure | 2:fd026fcfde94 | 420 | MODE_LOOPBACK, |
Just4pLeisure | 2:fd026fcfde94 | 421 | MODE_LISTENONLY, |
Just4pLeisure | 2:fd026fcfde94 | 422 | MODE_CONFIG, |
Just4pLeisure | 2:fd026fcfde94 | 423 | MODE_CONFIG |
Just4pLeisure | 2:fd026fcfde94 | 424 | }; |
Just4pLeisure | 0:f5d099885d3d | 425 | |
Just4pLeisure | 2:fd026fcfde94 | 426 | if (mode == _M_RESET) { |
Just4pLeisure | 0:f5d099885d3d | 427 | mcpReset(obj); |
Just4pLeisure | 0:f5d099885d3d | 428 | } |
Just4pLeisure | 0:f5d099885d3d | 429 | if (mcpSetMode(obj, which[mode])) { |
Just4pLeisure | 0:f5d099885d3d | 430 | return 1; |
Just4pLeisure | 0:f5d099885d3d | 431 | } |
Just4pLeisure | 0:f5d099885d3d | 432 | return 0; |
Just4pLeisure | 0:f5d099885d3d | 433 | } |
Just4pLeisure | 2:fd026fcfde94 | 434 | |
Just4pLeisure | 2:fd026fcfde94 | 435 | /* Configure interrupt sources |
Just4pLeisure | 2:fd026fcfde94 | 436 | */ |
Just4pLeisure | 2:fd026fcfde94 | 437 | void mcpSetInterrupts(mcp_can_t *obj, const CANIrqs irqSet) |
Just4pLeisure | 2:fd026fcfde94 | 438 | { |
Just4pLeisure | 2:fd026fcfde94 | 439 | uint8_t which[] = { MCP_NO_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 440 | MCP_ALL_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 441 | MCP_RX_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 442 | MCP_TX_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 443 | MCP_RX0IF, |
Just4pLeisure | 2:fd026fcfde94 | 444 | MCP_RX1IF, |
Just4pLeisure | 2:fd026fcfde94 | 445 | MCP_TX0IF, |
Just4pLeisure | 2:fd026fcfde94 | 446 | MCP_TX1IF, |
Just4pLeisure | 2:fd026fcfde94 | 447 | MCP_TX2IF, |
Just4pLeisure | 2:fd026fcfde94 | 448 | MCP_ERRIF, |
Just4pLeisure | 2:fd026fcfde94 | 449 | MCP_WAKIF, |
Just4pLeisure | 2:fd026fcfde94 | 450 | MCP_MERRF |
Just4pLeisure | 2:fd026fcfde94 | 451 | }; |
Just4pLeisure | 2:fd026fcfde94 | 452 | |
Just4pLeisure | 2:fd026fcfde94 | 453 | mcpWrite(obj, MCP_CANINTE, which[irqSet]); |
Just4pLeisure | 2:fd026fcfde94 | 454 | } |
Just4pLeisure | 2:fd026fcfde94 | 455 | |
Just4pLeisure | 2:fd026fcfde94 | 456 | /* Report on the specified interrupt causes |
Just4pLeisure | 2:fd026fcfde94 | 457 | */ |
Just4pLeisure | 2:fd026fcfde94 | 458 | uint8_t mcpInterruptType(mcp_can_t *obj, const CANIrqs irqFlag) |
Just4pLeisure | 2:fd026fcfde94 | 459 | { |
Just4pLeisure | 2:fd026fcfde94 | 460 | uint8_t which[] = { MCP_NO_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 461 | MCP_ALL_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 462 | MCP_RX_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 463 | MCP_TX_INTS, |
Just4pLeisure | 2:fd026fcfde94 | 464 | MCP_RX0IF, |
Just4pLeisure | 2:fd026fcfde94 | 465 | MCP_RX1IF, |
Just4pLeisure | 2:fd026fcfde94 | 466 | MCP_TX0IF, |
Just4pLeisure | 2:fd026fcfde94 | 467 | MCP_TX1IF, |
Just4pLeisure | 2:fd026fcfde94 | 468 | MCP_TX2IF, |
Just4pLeisure | 2:fd026fcfde94 | 469 | MCP_ERRIF, |
Just4pLeisure | 2:fd026fcfde94 | 470 | MCP_WAKIF, |
Just4pLeisure | 2:fd026fcfde94 | 471 | MCP_MERRF |
Just4pLeisure | 2:fd026fcfde94 | 472 | }; |
Just4pLeisure | 2:fd026fcfde94 | 473 | |
Just4pLeisure | 2:fd026fcfde94 | 474 | return (mcpRead(obj, MCP_EFLG) & which[irqFlag]) ? 1 : 0; |
Just4pLeisure | 2:fd026fcfde94 | 475 | } |
Just4pLeisure | 2:fd026fcfde94 | 476 | |
Just4pLeisure | 2:fd026fcfde94 | 477 | /* Return contents of the interrupt flags register |
Just4pLeisure | 2:fd026fcfde94 | 478 | */ |
Just4pLeisure | 2:fd026fcfde94 | 479 | uint8_t mcpInterruptFlags(mcp_can_t *obj) |
Just4pLeisure | 2:fd026fcfde94 | 480 | { |
Just4pLeisure | 2:fd026fcfde94 | 481 | return (mcpRead(obj, MCP_EFLG)); |
Just4pLeisure | 2:fd026fcfde94 | 482 | } |