[136] | 1 | /*
|
---|
| 2 | mcp_can.cpp
|
---|
| 3 | 2012 Copyright (c) Seeed Technology Inc. All right reserved.
|
---|
| 4 |
|
---|
| 5 | Author:Loovee
|
---|
| 6 | Contributor: Cory J. Fowler
|
---|
| 7 | 2014-1-16
|
---|
| 8 | This library is free software; you can redistribute it and/or
|
---|
| 9 | modify it under the terms of the GNU Lesser General Public
|
---|
| 10 | License as published by the Free Software Foundation; either
|
---|
| 11 | version 2.1 of the License, or (at your option) any later version.
|
---|
| 12 |
|
---|
| 13 | This library is distributed in the hope that it will be useful,
|
---|
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 16 | Lesser General Public License for more details.
|
---|
| 17 |
|
---|
| 18 | You should have received a copy of the GNU Lesser General Public
|
---|
| 19 | License along with this library; if not, write to the Free Software
|
---|
| 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-
|
---|
| 21 | 1301 USA
|
---|
| 22 | */
|
---|
| 23 | #include "mcp_can.h"
|
---|
| 24 |
|
---|
| 25 | #define spi_readwrite SPI.transfer
|
---|
| 26 | #define spi_read() spi_readwrite(0x00)
|
---|
| 27 |
|
---|
| 28 | #define CHECK_RXBID(rxbid) do { \
|
---|
| 29 | if (!((rxbid == 0) || (rxbid == 1))) { \
|
---|
| 30 | return CAN_FAIL; \
|
---|
| 31 | } \
|
---|
| 32 | } while(false)
|
---|
| 33 |
|
---|
| 34 | #define CHECK_LEN(len) do { \
|
---|
| 35 | if (len > 8) { \
|
---|
| 36 | return CAN_FAIL; \
|
---|
| 37 | } \
|
---|
| 38 | } while(false)
|
---|
| 39 |
|
---|
| 40 | #define CHECK_TXBID(txbid) do { \
|
---|
| 41 | if (!((txbid == 0) || (txbid == 1) || (txbid == 2))) { \
|
---|
| 42 | return CAN_FAIL; \
|
---|
| 43 | } \
|
---|
| 44 | } while(false)
|
---|
| 45 |
|
---|
| 46 | /*********************************************************************************************************
|
---|
| 47 | ** Function name: mcp2515_reset
|
---|
| 48 | ** Descriptions: reset the device
|
---|
| 49 | *********************************************************************************************************/
|
---|
| 50 | void MCP_CAN::mcp2515_reset(void)
|
---|
| 51 | {
|
---|
| 52 | MCP2515_SELECT();
|
---|
| 53 | spi_readwrite(MCP_RESET);
|
---|
| 54 | MCP2515_UNSELECT();
|
---|
| 55 | delay(10);
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | /*********************************************************************************************************
|
---|
| 59 | ** Function name: mcp2515_readRegister
|
---|
| 60 | ** Descriptions: read register
|
---|
| 61 | *********************************************************************************************************/
|
---|
| 62 | INT8U MCP_CAN::mcp2515_readRegister(const INT8U address)
|
---|
| 63 | {
|
---|
| 64 | INT8U ret;
|
---|
| 65 |
|
---|
| 66 | MCP2515_SELECT();
|
---|
| 67 | spi_readwrite(MCP_READ);
|
---|
| 68 | spi_readwrite(address);
|
---|
| 69 | ret = spi_read();
|
---|
| 70 | MCP2515_UNSELECT();
|
---|
| 71 |
|
---|
| 72 | return ret;
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | /*********************************************************************************************************
|
---|
| 76 | ** Function name: mcp2515_readRegisterS
|
---|
| 77 | ** Descriptions: read registerS
|
---|
| 78 | *********************************************************************************************************/
|
---|
| 79 | void MCP_CAN::mcp2515_readRegisterS(const INT8U address, INT8U values[], const INT8U n)
|
---|
| 80 | {
|
---|
| 81 | INT8U i;
|
---|
| 82 | MCP2515_SELECT();
|
---|
| 83 | spi_readwrite(MCP_READ);
|
---|
| 84 | spi_readwrite(address);
|
---|
| 85 | // mcp2515 has auto-increment of address-pointer
|
---|
| 86 | for (i=0; i<n && i<CAN_MAX_CHAR_IN_MESSAGE; i++) {
|
---|
| 87 | values[i] = spi_read();
|
---|
| 88 | }
|
---|
| 89 | MCP2515_UNSELECT();
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | /*********************************************************************************************************
|
---|
| 93 | ** Function name: mcp2515_setRegister
|
---|
| 94 | ** Descriptions: set register
|
---|
| 95 | *********************************************************************************************************/
|
---|
| 96 | void MCP_CAN::mcp2515_setRegister(const INT8U address, const INT8U value)
|
---|
| 97 | {
|
---|
| 98 | MCP2515_SELECT();
|
---|
| 99 | spi_readwrite(MCP_WRITE);
|
---|
| 100 | spi_readwrite(address);
|
---|
| 101 | spi_readwrite(value);
|
---|
| 102 | MCP2515_UNSELECT();
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | /*********************************************************************************************************
|
---|
| 106 | ** Function name: mcp2515_setRegisterS
|
---|
| 107 | ** Descriptions: set registerS
|
---|
| 108 | *********************************************************************************************************/
|
---|
| 109 | void MCP_CAN::mcp2515_setRegisterS(const INT8U address, const INT8U values[], const INT8U n)
|
---|
| 110 | {
|
---|
| 111 | INT8U i;
|
---|
| 112 | MCP2515_SELECT();
|
---|
| 113 | spi_readwrite(MCP_WRITE);
|
---|
| 114 | spi_readwrite(address);
|
---|
| 115 |
|
---|
| 116 | for (i=0; i<n; i++)
|
---|
| 117 | {
|
---|
| 118 | spi_readwrite(values[i]);
|
---|
| 119 | }
|
---|
| 120 | MCP2515_UNSELECT();
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | /*********************************************************************************************************
|
---|
| 124 | ** Function name: mcp2515_modifyRegister
|
---|
| 125 | ** Descriptions: set bit of one register
|
---|
| 126 | *********************************************************************************************************/
|
---|
| 127 | void MCP_CAN::mcp2515_modifyRegister(const INT8U address, const INT8U mask, const INT8U data)
|
---|
| 128 | {
|
---|
| 129 | MCP2515_SELECT();
|
---|
| 130 | spi_readwrite(MCP_BITMOD);
|
---|
| 131 | spi_readwrite(address);
|
---|
| 132 | spi_readwrite(mask);
|
---|
| 133 | spi_readwrite(data);
|
---|
| 134 | MCP2515_UNSELECT();
|
---|
| 135 | }
|
---|
| 136 |
|
---|
| 137 | /*********************************************************************************************************
|
---|
| 138 | ** Function name: mcp2515_readStatus
|
---|
| 139 | ** Descriptions: read mcp2515's Status
|
---|
| 140 | *********************************************************************************************************/
|
---|
| 141 | INT8U MCP_CAN::mcp2515_readStatus(void)
|
---|
| 142 | {
|
---|
| 143 | INT8U i;
|
---|
| 144 | MCP2515_SELECT();
|
---|
| 145 | spi_readwrite(MCP_READ_STATUS);
|
---|
| 146 | i = spi_read();
|
---|
| 147 | MCP2515_UNSELECT();
|
---|
| 148 |
|
---|
| 149 | return i;
|
---|
| 150 | }
|
---|
| 151 |
|
---|
| 152 | /*********************************************************************************************************
|
---|
| 153 | ** Function name: mcp2515_setCANCTRL_Mode
|
---|
| 154 | ** Descriptions: set control mode
|
---|
| 155 | *********************************************************************************************************/
|
---|
| 156 | INT8U MCP_CAN::mcp2515_setCANCTRL_Mode(const INT8U newmode)
|
---|
| 157 | {
|
---|
| 158 | INT8U i;
|
---|
| 159 |
|
---|
| 160 | mcp2515_modifyRegister(MCP_CANCTRL, MODE_MASK, newmode);
|
---|
| 161 |
|
---|
| 162 | i = mcp2515_readRegister(MCP_CANCTRL);
|
---|
| 163 | i &= MODE_MASK;
|
---|
| 164 |
|
---|
| 165 | if ( i == newmode )
|
---|
| 166 | {
|
---|
| 167 | return MCP2515_OK;
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | return MCP2515_FAIL;
|
---|
| 171 |
|
---|
| 172 | }
|
---|
| 173 |
|
---|
| 174 | /*********************************************************************************************************
|
---|
| 175 | ** Function name: mcp2515_configRate
|
---|
| 176 | ** Descriptions: set boadrate
|
---|
| 177 | *********************************************************************************************************/
|
---|
| 178 | INT8U MCP_CAN::mcp2515_configRate(const INT8U canSpeed)
|
---|
| 179 | {
|
---|
| 180 | INT8U set, cfg1, cfg2, cfg3;
|
---|
| 181 | set = 1;
|
---|
| 182 | switch (canSpeed)
|
---|
| 183 | {
|
---|
| 184 | case (CAN_5KBPS):
|
---|
| 185 | cfg1 = MCP_16MHz_5kBPS_CFG1;
|
---|
| 186 | cfg2 = MCP_16MHz_5kBPS_CFG2;
|
---|
| 187 | cfg3 = MCP_16MHz_5kBPS_CFG3;
|
---|
| 188 | break;
|
---|
| 189 |
|
---|
| 190 | case (CAN_10KBPS):
|
---|
| 191 | cfg1 = MCP_16MHz_10kBPS_CFG1;
|
---|
| 192 | cfg2 = MCP_16MHz_10kBPS_CFG2;
|
---|
| 193 | cfg3 = MCP_16MHz_10kBPS_CFG3;
|
---|
| 194 | break;
|
---|
| 195 |
|
---|
| 196 | case (CAN_20KBPS):
|
---|
| 197 | cfg1 = MCP_16MHz_20kBPS_CFG1;
|
---|
| 198 | cfg2 = MCP_16MHz_20kBPS_CFG2;
|
---|
| 199 | cfg3 = MCP_16MHz_20kBPS_CFG3;
|
---|
| 200 | break;
|
---|
| 201 |
|
---|
| 202 | case (CAN_31K25BPS):
|
---|
| 203 | cfg1 = MCP_16MHz_31k25BPS_CFG1;
|
---|
| 204 | cfg2 = MCP_16MHz_31k25BPS_CFG2;
|
---|
| 205 | cfg3 = MCP_16MHz_31k25BPS_CFG3;
|
---|
| 206 | break;
|
---|
| 207 |
|
---|
| 208 | case (CAN_33KBPS):
|
---|
| 209 | cfg1 = MCP_16MHz_33kBPS_CFG1;
|
---|
| 210 | cfg2 = MCP_16MHz_33kBPS_CFG2;
|
---|
| 211 | cfg3 = MCP_16MHz_33kBPS_CFG3;
|
---|
| 212 | break;
|
---|
| 213 |
|
---|
| 214 | case (CAN_40KBPS):
|
---|
| 215 | cfg1 = MCP_16MHz_40kBPS_CFG1;
|
---|
| 216 | cfg2 = MCP_16MHz_40kBPS_CFG2;
|
---|
| 217 | cfg3 = MCP_16MHz_40kBPS_CFG3;
|
---|
| 218 | break;
|
---|
| 219 |
|
---|
| 220 | case (CAN_50KBPS):
|
---|
| 221 | cfg1 = MCP_16MHz_50kBPS_CFG1;
|
---|
| 222 | cfg2 = MCP_16MHz_50kBPS_CFG2;
|
---|
| 223 | cfg3 = MCP_16MHz_50kBPS_CFG3;
|
---|
| 224 | break;
|
---|
| 225 |
|
---|
| 226 | case (CAN_80KBPS):
|
---|
| 227 | cfg1 = MCP_16MHz_80kBPS_CFG1;
|
---|
| 228 | cfg2 = MCP_16MHz_80kBPS_CFG2;
|
---|
| 229 | cfg3 = MCP_16MHz_80kBPS_CFG3;
|
---|
| 230 | break;
|
---|
| 231 |
|
---|
| 232 | case (CAN_83K3BPS):
|
---|
| 233 | cfg1 = MCP_16MHz_83k3BPS_CFG1;
|
---|
| 234 | cfg2 = MCP_16MHz_83k3BPS_CFG2;
|
---|
| 235 | cfg3 = MCP_16MHz_83k3BPS_CFG3;
|
---|
| 236 | break;
|
---|
| 237 |
|
---|
| 238 | case (CAN_95KBPS):
|
---|
| 239 | cfg1 = MCP_16MHz_95kBPS_CFG1;
|
---|
| 240 | cfg2 = MCP_16MHz_95kBPS_CFG2;
|
---|
| 241 | cfg3 = MCP_16MHz_95kBPS_CFG3;
|
---|
| 242 | break;
|
---|
| 243 |
|
---|
| 244 | case (CAN_100KBPS): /* 100KBPS */
|
---|
| 245 | cfg1 = MCP_16MHz_100kBPS_CFG1;
|
---|
| 246 | cfg2 = MCP_16MHz_100kBPS_CFG2;
|
---|
| 247 | cfg3 = MCP_16MHz_100kBPS_CFG3;
|
---|
| 248 | break;
|
---|
| 249 |
|
---|
| 250 | case (CAN_125KBPS):
|
---|
| 251 | cfg1 = MCP_16MHz_125kBPS_CFG1;
|
---|
| 252 | cfg2 = MCP_16MHz_125kBPS_CFG2;
|
---|
| 253 | cfg3 = MCP_16MHz_125kBPS_CFG3;
|
---|
| 254 | break;
|
---|
| 255 |
|
---|
| 256 | case (CAN_200KBPS):
|
---|
| 257 | cfg1 = MCP_16MHz_200kBPS_CFG1;
|
---|
| 258 | cfg2 = MCP_16MHz_200kBPS_CFG2;
|
---|
| 259 | cfg3 = MCP_16MHz_200kBPS_CFG3;
|
---|
| 260 | break;
|
---|
| 261 |
|
---|
| 262 | case (CAN_250KBPS):
|
---|
| 263 | cfg1 = MCP_16MHz_250kBPS_CFG1;
|
---|
| 264 | cfg2 = MCP_16MHz_250kBPS_CFG2;
|
---|
| 265 | cfg3 = MCP_16MHz_250kBPS_CFG3;
|
---|
| 266 | break;
|
---|
| 267 |
|
---|
| 268 | case (CAN_500KBPS):
|
---|
| 269 | cfg1 = MCP_16MHz_500kBPS_CFG1;
|
---|
| 270 | cfg2 = MCP_16MHz_500kBPS_CFG2;
|
---|
| 271 | cfg3 = MCP_16MHz_500kBPS_CFG3;
|
---|
| 272 | break;
|
---|
| 273 |
|
---|
| 274 | case (CAN_1000KBPS):
|
---|
| 275 | cfg1 = MCP_16MHz_1000kBPS_CFG1;
|
---|
| 276 | cfg2 = MCP_16MHz_1000kBPS_CFG2;
|
---|
| 277 | cfg3 = MCP_16MHz_1000kBPS_CFG3;
|
---|
| 278 | break;
|
---|
| 279 |
|
---|
| 280 | default:
|
---|
| 281 | set = 0;
|
---|
| 282 | break;
|
---|
| 283 | }
|
---|
| 284 |
|
---|
| 285 | if (set) {
|
---|
| 286 | mcp2515_setRegister(MCP_CNF1, cfg1);
|
---|
| 287 | mcp2515_setRegister(MCP_CNF2, cfg2);
|
---|
| 288 | mcp2515_setRegister(MCP_CNF3, cfg3);
|
---|
| 289 | return MCP2515_OK;
|
---|
| 290 | }
|
---|
| 291 | else {
|
---|
| 292 | return MCP2515_FAIL;
|
---|
| 293 | }
|
---|
| 294 | }
|
---|
| 295 |
|
---|
| 296 | /*********************************************************************************************************
|
---|
| 297 | ** Function name: mcp2515_initCANBuffers
|
---|
| 298 | ** Descriptions: init canbuffers
|
---|
| 299 | *********************************************************************************************************/
|
---|
| 300 | void MCP_CAN::mcp2515_initCANBuffers(void)
|
---|
| 301 | {
|
---|
| 302 | INT8U i, a1, a2, a3;
|
---|
| 303 |
|
---|
| 304 | INT8U std = 0;
|
---|
| 305 | INT8U ext = 1;
|
---|
| 306 | INT32U ulMask = 0xffffffff, ulFilt = 0x00;
|
---|
| 307 |
|
---|
| 308 |
|
---|
| 309 | mcp2515_write_id(MCP_RXM0SIDH, ext, ulMask); /*Set both masks to 0xff */
|
---|
| 310 | mcp2515_write_id(MCP_RXM1SIDH, ext, ulMask); /*Mask register ignores ext bit */
|
---|
| 311 |
|
---|
| 312 | /* Set all filters to 0 */
|
---|
| 313 | mcp2515_write_id(MCP_RXF0SIDH, std, ulFilt); /* RXB0: standard */
|
---|
| 314 | mcp2515_write_id(MCP_RXF1SIDH, std, ulFilt); /* RXB1: standard */
|
---|
| 315 | mcp2515_write_id(MCP_RXF2SIDH, std, ulFilt); /* RXB2: standard */
|
---|
| 316 | mcp2515_write_id(MCP_RXF3SIDH, std, ulFilt); /* RXB3: standard */
|
---|
| 317 | mcp2515_write_id(MCP_RXF4SIDH, std, ulFilt);
|
---|
| 318 | mcp2515_write_id(MCP_RXF5SIDH, std, ulFilt);
|
---|
| 319 |
|
---|
| 320 | /* Clear, deactivate the three */
|
---|
| 321 | /* transmit buffers */
|
---|
| 322 | /* TXBnCTRL -> TXBnD7 */
|
---|
| 323 | a1 = MCP_TXB0CTRL;
|
---|
| 324 | a2 = MCP_TXB1CTRL;
|
---|
| 325 | a3 = MCP_TXB2CTRL;
|
---|
| 326 | for (i = 0; i < 14; i++) { /* in-buffer loop */
|
---|
| 327 | mcp2515_setRegister(a1, 0);
|
---|
| 328 | mcp2515_setRegister(a2, 0);
|
---|
| 329 | mcp2515_setRegister(a3, 0);
|
---|
| 330 | a1++;
|
---|
| 331 | a2++;
|
---|
| 332 | a3++;
|
---|
| 333 | }
|
---|
| 334 | mcp2515_setRegister(MCP_RXB0CTRL, 0x00);
|
---|
| 335 | mcp2515_setRegister(MCP_RXB1CTRL, 0xff);
|
---|
| 336 | }
|
---|
| 337 |
|
---|
| 338 | /*********************************************************************************************************
|
---|
| 339 | ** Function name: mcp2515_init
|
---|
| 340 | ** Descriptions: init the device
|
---|
| 341 | *********************************************************************************************************/
|
---|
| 342 | INT8U MCP_CAN::mcp2515_init(const INT8U canSpeed) /* mcp2515init */
|
---|
| 343 | {
|
---|
| 344 |
|
---|
| 345 | INT8U res;
|
---|
| 346 |
|
---|
| 347 | mcp2515_reset();
|
---|
| 348 |
|
---|
| 349 | res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
|
---|
| 350 | if(res > 0)
|
---|
| 351 | {
|
---|
| 352 | #if DEBUG_MODE
|
---|
| 353 | Serial.print("Enter setting mode fall\r\n");
|
---|
| 354 | #endif
|
---|
| 355 | return res;
|
---|
| 356 | }
|
---|
| 357 | #if DEBUG_MODE
|
---|
| 358 | Serial.print("Enter setting mode success \r\n");
|
---|
| 359 | #endif
|
---|
| 360 |
|
---|
| 361 | if(mcp2515_configRate(canSpeed))
|
---|
| 362 | {
|
---|
| 363 | #if DEBUG_MODE
|
---|
| 364 | Serial.print("set rate fall!!\r\n");
|
---|
| 365 | #endif
|
---|
| 366 | return res;
|
---|
| 367 | }
|
---|
| 368 | #if DEBUG_MODE
|
---|
| 369 | Serial.print("set rate success!!\r\n");
|
---|
| 370 | #endif
|
---|
| 371 |
|
---|
| 372 | if ( res == MCP2515_OK ) {
|
---|
| 373 |
|
---|
| 374 | /* init canbuffers */
|
---|
| 375 | mcp2515_initCANBuffers();
|
---|
| 376 |
|
---|
| 377 | /* interrupt mode */
|
---|
| 378 | mcp2515_setRegister(MCP_CANINTE, 0x00);
|
---|
| 379 |
|
---|
| 380 | /* enter normal mode */
|
---|
| 381 | res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
|
---|
| 382 | if(res)
|
---|
| 383 | {
|
---|
| 384 | #if DEBUG_MODE
|
---|
| 385 | Serial.print("Enter Normal Mode Fall!!\r\n");
|
---|
| 386 | #endif
|
---|
| 387 | return res;
|
---|
| 388 | }
|
---|
| 389 |
|
---|
| 390 |
|
---|
| 391 | #if DEBUG_MODE
|
---|
| 392 | Serial.print("Enter Normal Mode Success!!\r\n");
|
---|
| 393 | #endif
|
---|
| 394 |
|
---|
| 395 | }
|
---|
| 396 | return res;
|
---|
| 397 |
|
---|
| 398 | }
|
---|
| 399 |
|
---|
| 400 | /*********************************************************************************************************
|
---|
| 401 | ** Function name: mcp2515_write_id
|
---|
| 402 | ** Descriptions: write can id
|
---|
| 403 | *********************************************************************************************************/
|
---|
| 404 | void MCP_CAN::mcp2515_write_id( const INT8U mcp_addr, const INT8U ext, const INT32U id )
|
---|
| 405 | {
|
---|
| 406 | uint16_t canid;
|
---|
| 407 | INT8U tbufdata[4];
|
---|
| 408 |
|
---|
| 409 | canid = (uint16_t)(id & 0x0FFFF);
|
---|
| 410 |
|
---|
| 411 | if ( ext == 1)
|
---|
| 412 | {
|
---|
| 413 | tbufdata[MCP_EID0] = (INT8U) (canid & 0xFF);
|
---|
| 414 | tbufdata[MCP_EID8] = (INT8U) (canid >> 8);
|
---|
| 415 | canid = (uint16_t)(id >> 16);
|
---|
| 416 | tbufdata[MCP_SIDL] = (INT8U) (canid & 0x03);
|
---|
| 417 | tbufdata[MCP_SIDL] += (INT8U) ((canid & 0x1C) << 3);
|
---|
| 418 | tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M;
|
---|
| 419 | tbufdata[MCP_SIDH] = (INT8U) (canid >> 5 );
|
---|
| 420 | }
|
---|
| 421 | else
|
---|
| 422 | {
|
---|
| 423 | tbufdata[MCP_SIDH] = (INT8U) (canid >> 3 );
|
---|
| 424 | tbufdata[MCP_SIDL] = (INT8U) ((canid & 0x07 ) << 5);
|
---|
| 425 | tbufdata[MCP_EID0] = 0;
|
---|
| 426 | tbufdata[MCP_EID8] = 0;
|
---|
| 427 | }
|
---|
| 428 | mcp2515_setRegisterS( mcp_addr, tbufdata, 4 );
|
---|
| 429 | }
|
---|
| 430 |
|
---|
| 431 | /*********************************************************************************************************
|
---|
| 432 | ** Function name: mcp2515_read_id
|
---|
| 433 | ** Descriptions: read can id
|
---|
| 434 | *********************************************************************************************************/
|
---|
| 435 | void MCP_CAN::mcp2515_read_id( const INT8U mcp_addr, INT8U* ext, INT32U* id )
|
---|
| 436 | {
|
---|
| 437 | INT8U tbufdata[4];
|
---|
| 438 |
|
---|
| 439 | *ext = 0;
|
---|
| 440 | *id = 0;
|
---|
| 441 |
|
---|
| 442 | mcp2515_readRegisterS( mcp_addr, tbufdata, 4 );
|
---|
| 443 |
|
---|
| 444 | *id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
|
---|
| 445 |
|
---|
| 446 | if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M )
|
---|
| 447 | {
|
---|
| 448 | /* extended id */
|
---|
| 449 | *id = (*id<<2) + (tbufdata[MCP_SIDL] & 0x03);
|
---|
| 450 | *id = (*id<<8) + tbufdata[MCP_EID8];
|
---|
| 451 | *id = (*id<<8) + tbufdata[MCP_EID0];
|
---|
| 452 | *ext = 1;
|
---|
| 453 | }
|
---|
| 454 | }
|
---|
| 455 |
|
---|
| 456 | /*********************************************************************************************************
|
---|
| 457 | ** Function name: mcp2515_write_canMsg
|
---|
| 458 | ** Descriptions: write msg
|
---|
| 459 | *********************************************************************************************************/
|
---|
| 460 | void MCP_CAN::mcp2515_write_canMsg( INT8U txbid, INT32U id, INT8U len, INT8U *pData, INT8U ext, INT8U rtr )
|
---|
| 461 | {
|
---|
| 462 | INT8U ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
|
---|
| 463 | INT8U mcp_addr = ctrlregs[txbid] + 1;
|
---|
| 464 |
|
---|
| 465 | mcp2515_setRegisterS(mcp_addr+5, pData, len ); /* write data bytes */
|
---|
| 466 | if ( rtr == 1) /* if RTR set bit in byte */
|
---|
| 467 | {
|
---|
| 468 | len |= MCP_RTR_MASK;
|
---|
| 469 | }
|
---|
| 470 | mcp2515_setRegister((mcp_addr+4), len ); /* write the RTR and DLC */
|
---|
| 471 | mcp2515_write_id(mcp_addr, ext, id ); /* write CAN id */
|
---|
| 472 |
|
---|
| 473 | }
|
---|
| 474 |
|
---|
| 475 | /*********************************************************************************************************
|
---|
| 476 | ** Function name: mcp2515_read_canMsg
|
---|
| 477 | ** Descriptions: read message
|
---|
| 478 | *********************************************************************************************************/
|
---|
| 479 | void MCP_CAN::mcp2515_read_canMsg( INT8U rxbid, INT32U *p_id, INT8U *p_len, INT8U *p_buf, INT8U *p_ext, INT8U *p_rtr) /* read can msg */
|
---|
| 480 | {
|
---|
| 481 | INT8U mcp_addr = (rxbid == 0)? MCP_RXBUF_0 : MCP_RXBUF_1;
|
---|
| 482 | INT8U ctrl;
|
---|
| 483 |
|
---|
| 484 | mcp2515_read_id( mcp_addr, p_ext, p_id );
|
---|
| 485 |
|
---|
| 486 | ctrl = mcp2515_readRegister( mcp_addr-1 );
|
---|
| 487 | *p_len = mcp2515_readRegister( mcp_addr+4 );
|
---|
| 488 |
|
---|
| 489 | if ((ctrl & 0x08)) {
|
---|
| 490 | *p_rtr = 1;
|
---|
| 491 | }
|
---|
| 492 | else {
|
---|
| 493 | *p_rtr = 0;
|
---|
| 494 | }
|
---|
| 495 |
|
---|
| 496 | *p_len &= MCP_DLC_MASK;
|
---|
| 497 | mcp2515_readRegisterS( mcp_addr+5, p_buf, *p_len );
|
---|
| 498 | }
|
---|
| 499 |
|
---|
| 500 | /*********************************************************************************************************
|
---|
| 501 | ** Function name: sendMsg
|
---|
| 502 | ** Descriptions: send message
|
---|
| 503 | *********************************************************************************************************/
|
---|
| 504 | void MCP_CAN::mcp2515_start_transmit(INT8U txbid) /* start transmit */
|
---|
| 505 | {
|
---|
| 506 | INT8U ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
|
---|
| 507 | INT8U mcp_addr = ctrlregs[txbid];
|
---|
| 508 |
|
---|
| 509 | mcp2515_modifyRegister( mcp_addr, MCP_TXB_TXREQ_M, MCP_TXB_TXREQ_M );
|
---|
| 510 | }
|
---|
| 511 |
|
---|
| 512 | /*********************************************************************************************************
|
---|
| 513 | ** Function name: sendMsg
|
---|
| 514 | ** Descriptions: send message
|
---|
| 515 | *********************************************************************************************************/
|
---|
| 516 | INT8U MCP_CAN::mcp2515_getNextFreeTXBuf(INT8U *txbuf_n) /* get Next free txbuf */
|
---|
| 517 | {
|
---|
| 518 | INT8U res, i, ctrlval;
|
---|
| 519 | INT8U ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
|
---|
| 520 |
|
---|
| 521 | res = MCP_ALLTXBUSY;
|
---|
| 522 | *txbuf_n = 0x00;
|
---|
| 523 |
|
---|
| 524 | /* check all 3 TX-Buffers */
|
---|
| 525 | for (i=0; i<MCP_N_TXBUFFERS; i++) {
|
---|
| 526 | ctrlval = mcp2515_readRegister( ctrlregs[i] );
|
---|
| 527 | if ( (ctrlval & MCP_TXB_TXREQ_M) == 0 ) {
|
---|
| 528 | *txbuf_n = ctrlregs[i]+1; /* return SIDH-address of Buffe */
|
---|
| 529 | /* r */
|
---|
| 530 | res = MCP2515_OK;
|
---|
| 531 | return res; /* ! function exit */
|
---|
| 532 | }
|
---|
| 533 | }
|
---|
| 534 | return res;
|
---|
| 535 | }
|
---|
| 536 |
|
---|
| 537 | /*********************************************************************************************************
|
---|
| 538 | ** Function name: set CS
|
---|
| 539 | ** Descriptions: init CS pin and set UNSELECTED
|
---|
| 540 | *********************************************************************************************************/
|
---|
| 541 | MCP_CAN::MCP_CAN(INT8U _CS)
|
---|
| 542 | {
|
---|
| 543 | SPICS = _CS;
|
---|
| 544 | pinMode(SPICS, OUTPUT);
|
---|
| 545 | MCP2515_UNSELECT();
|
---|
| 546 | }
|
---|
| 547 |
|
---|
| 548 | /*********************************************************************************************************
|
---|
| 549 | ** Function name: init
|
---|
| 550 | ** Descriptions: init can and set speed
|
---|
| 551 | *********************************************************************************************************/
|
---|
| 552 | INT8U MCP_CAN::begin(INT8U speedset)
|
---|
| 553 | {
|
---|
| 554 | INT8U res;
|
---|
| 555 |
|
---|
| 556 | SPI.begin();
|
---|
| 557 | res = mcp2515_init(speedset);
|
---|
| 558 | if (res == MCP2515_OK) return CAN_OK;
|
---|
| 559 | else return CAN_FAILINIT;
|
---|
| 560 | }
|
---|
| 561 |
|
---|
| 562 | /*********************************************************************************************************
|
---|
| 563 | ** Function name: enableInterrupt
|
---|
| 564 | ** Descriptions: Enable Interrupt
|
---|
| 565 | *********************************************************************************************************/
|
---|
| 566 | INT8U MCP_CAN::enableInterrupt(INT8U mask)
|
---|
| 567 | {
|
---|
| 568 | mcp2515_modifyRegister(MCP_CANINTE, mask, mask);
|
---|
| 569 | return CAN_OK;
|
---|
| 570 | }
|
---|
| 571 |
|
---|
| 572 | /*********************************************************************************************************
|
---|
| 573 | ** Function name: disableInterrupt
|
---|
| 574 | ** Descriptions: Disable Interrupt
|
---|
| 575 | *********************************************************************************************************/
|
---|
| 576 | INT8U MCP_CAN::disableInterrupt(INT8U mask)
|
---|
| 577 | {
|
---|
| 578 | mcp2515_modifyRegister(MCP_CANINTE, mask, !mask);
|
---|
| 579 | return CAN_OK;
|
---|
| 580 | }
|
---|
| 581 |
|
---|
| 582 | /*********************************************************************************************************
|
---|
| 583 | ** Function name: attachInterrupt
|
---|
| 584 | ** Descriptions: Attach Interrupt
|
---|
| 585 | *********************************************************************************************************/
|
---|
| 586 | INT8U MCP_CAN::attachInterrupt(uint32_t ulPin, voidFuncPtr callback)
|
---|
| 587 | {
|
---|
| 588 | ::attachInterrupt( ulPin, callback, FALLING ) ;
|
---|
| 589 | return CAN_OK;
|
---|
| 590 | }
|
---|
| 591 |
|
---|
| 592 | /*********************************************************************************************************
|
---|
| 593 | ** Function name: init_Mask
|
---|
| 594 | ** Descriptions: init canid Masks
|
---|
| 595 | *********************************************************************************************************/
|
---|
| 596 | INT8U MCP_CAN::init_Mask(INT8U num, INT32U ulData, INT8U ext)
|
---|
| 597 | {
|
---|
| 598 | INT8U res = MCP2515_OK;
|
---|
| 599 | #if DEBUG_MODE
|
---|
| 600 | Serial.print("Begin to set Mask!!\r\n");
|
---|
| 601 | #endif
|
---|
| 602 | res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
|
---|
| 603 | if(res > 0){
|
---|
| 604 | #if DEBUG_MODE
|
---|
| 605 | Serial.print("Enter setting mode fall\r\n");
|
---|
| 606 | #endif
|
---|
| 607 | return res;
|
---|
| 608 | }
|
---|
| 609 |
|
---|
| 610 | if (num == 0){
|
---|
| 611 | mcp2515_write_id(MCP_RXM0SIDH, ext, ulData);
|
---|
| 612 | }
|
---|
| 613 | else if(num == 1){
|
---|
| 614 | mcp2515_write_id(MCP_RXM1SIDH, ext, ulData);
|
---|
| 615 | }
|
---|
| 616 | else res = MCP2515_FAIL;
|
---|
| 617 |
|
---|
| 618 | res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
|
---|
| 619 | if(res > 0){
|
---|
| 620 | #if DEBUG_MODE
|
---|
| 621 | Serial.print("Enter normal mode fall\r\n");
|
---|
| 622 | #endif
|
---|
| 623 | return res;
|
---|
| 624 | }
|
---|
| 625 | #if DEBUG_MODE
|
---|
| 626 | Serial.print("set Mask success!!\r\n");
|
---|
| 627 | #endif
|
---|
| 628 | return res;
|
---|
| 629 | }
|
---|
| 630 |
|
---|
| 631 | /*********************************************************************************************************
|
---|
| 632 | ** Function name: init_Filter
|
---|
| 633 | ** Descriptions: init canid filters
|
---|
| 634 | *********************************************************************************************************/
|
---|
| 635 | INT8U MCP_CAN::init_Filter(INT8U num, INT32U ulData, INT8U ext)
|
---|
| 636 | {
|
---|
| 637 | INT8U res = MCP2515_OK;
|
---|
| 638 | #if DEBUG_MODE
|
---|
| 639 | Serial.print("Begin to set Filter!!\r\n");
|
---|
| 640 | #endif
|
---|
| 641 | res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
|
---|
| 642 | if(res > 0)
|
---|
| 643 | {
|
---|
| 644 | #if DEBUG_MODE
|
---|
| 645 | Serial.print("Enter setting mode fall\r\n");
|
---|
| 646 | #endif
|
---|
| 647 | return res;
|
---|
| 648 | }
|
---|
| 649 |
|
---|
| 650 | switch( num )
|
---|
| 651 | {
|
---|
| 652 | case 0:
|
---|
| 653 | mcp2515_write_id(MCP_RXF0SIDH, ext, ulData);
|
---|
| 654 | break;
|
---|
| 655 |
|
---|
| 656 | case 1:
|
---|
| 657 | mcp2515_write_id(MCP_RXF1SIDH, ext, ulData);
|
---|
| 658 | break;
|
---|
| 659 |
|
---|
| 660 | case 2:
|
---|
| 661 | mcp2515_write_id(MCP_RXF2SIDH, ext, ulData);
|
---|
| 662 | break;
|
---|
| 663 |
|
---|
| 664 | case 3:
|
---|
| 665 | mcp2515_write_id(MCP_RXF3SIDH, ext, ulData);
|
---|
| 666 | break;
|
---|
| 667 |
|
---|
| 668 | case 4:
|
---|
| 669 | mcp2515_write_id(MCP_RXF4SIDH, ext, ulData);
|
---|
| 670 | break;
|
---|
| 671 |
|
---|
| 672 | case 5:
|
---|
| 673 | mcp2515_write_id(MCP_RXF5SIDH, ext, ulData);
|
---|
| 674 | break;
|
---|
| 675 |
|
---|
| 676 | default:
|
---|
| 677 | res = MCP2515_FAIL;
|
---|
| 678 | }
|
---|
| 679 |
|
---|
| 680 | res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
|
---|
| 681 | if(res > 0)
|
---|
| 682 | {
|
---|
| 683 | #if DEBUG_MODE
|
---|
| 684 | Serial.print("Enter normal mode fall\r\nSet filter fail!!\r\n");
|
---|
| 685 | #else
|
---|
| 686 | delay(10);
|
---|
| 687 | #endif
|
---|
| 688 | return res;
|
---|
| 689 | }
|
---|
| 690 | #if DEBUG_MODE
|
---|
| 691 | Serial.print("set Filter success!!\r\n");
|
---|
| 692 | #else
|
---|
| 693 | delay(10);
|
---|
| 694 | #endif
|
---|
| 695 |
|
---|
| 696 | return res;
|
---|
| 697 | }
|
---|
| 698 |
|
---|
| 699 | /*********************************************************************************************************
|
---|
| 700 | ** Function name: startReceive
|
---|
| 701 | ** Descriptions: start Receive
|
---|
| 702 | *********************************************************************************************************/
|
---|
| 703 | INT8U MCP_CAN::startReceive(INT8U rxbid)
|
---|
| 704 | {
|
---|
| 705 | CHECK_RXBID(rxbid);
|
---|
| 706 |
|
---|
| 707 | #if (DEBUG_RXANY==1)
|
---|
| 708 | /* enable both receive-buffers */
|
---|
| 709 | /* to receive any message */
|
---|
| 710 | /* and enable rollover */
|
---|
| 711 | if (rxbid == 0) {
|
---|
| 712 | mcp2515_modifyRegister(MCP_RXB0CTRL,
|
---|
| 713 | MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
|
---|
| 714 | MCP_RXB_RX_ANY);
|
---|
| 715 | }else{
|
---|
| 716 | mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
|
---|
| 717 | MCP_RXB_RX_ANY);
|
---|
| 718 | }
|
---|
| 719 | #else
|
---|
| 720 | /* enable both receive-buffers */
|
---|
| 721 | /* to receive messages */
|
---|
| 722 | /* with std. and ext. identifie */
|
---|
| 723 | /* rs */
|
---|
| 724 | /* and enable rollover */
|
---|
| 725 | if (rxbid == 0) {
|
---|
| 726 | mcp2515_modifyRegister(MCP_RXB0CTRL,
|
---|
| 727 | MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
|
---|
| 728 | MCP_RXB_RX_STDEXT);
|
---|
| 729 | }else{
|
---|
| 730 | mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
|
---|
| 731 | MCP_RXB_RX_STDEXT);
|
---|
| 732 | }
|
---|
| 733 | #endif
|
---|
| 734 |
|
---|
| 735 | return CAN_OK;
|
---|
| 736 | }
|
---|
| 737 |
|
---|
| 738 | /*********************************************************************************************************
|
---|
| 739 | ** Function name: sendMsg
|
---|
| 740 | ** Descriptions: send message
|
---|
| 741 | *********************************************************************************************************/
|
---|
| 742 | INT8U MCP_CAN::sendMsg(INT8U txbid, INT32U id, INT8U len, INT8U *p_buf, INT8U ext, INT8U rtr)
|
---|
| 743 | {
|
---|
| 744 | INT8U intf_tbl[MCP_N_TXBUFFERS] = { MCP_TX0IF, MCP_TX1IF, MCP_TX2IF };
|
---|
| 745 | INT8U intf_bit = intf_tbl[txbid];
|
---|
| 746 |
|
---|
| 747 | CHECK_LEN(len);
|
---|
| 748 | CHECK_TXBID(txbid);
|
---|
| 749 |
|
---|
| 750 | mcp2515_write_canMsg(txbid, id, len, p_buf, ext, rtr);
|
---|
| 751 | mcp2515_modifyRegister(MCP_CANINTF, intf_bit, 0);
|
---|
| 752 | mcp2515_start_transmit( txbid );
|
---|
| 753 |
|
---|
| 754 | return CAN_OK;
|
---|
| 755 | }
|
---|
| 756 |
|
---|
| 757 | /*********************************************************************************************************
|
---|
| 758 | ** Function name: sendMsg
|
---|
| 759 | ** Descriptions: send buf
|
---|
| 760 | *********************************************************************************************************/
|
---|
| 761 | INT8U MCP_CAN::sendMsg(INT8U txbid, INT32U id, INT8U len, INT8U *p_buf, INT8U ext)
|
---|
| 762 | {
|
---|
| 763 | return sendMsg(txbid, id, len, p_buf, ext, 0);
|
---|
| 764 | }
|
---|
| 765 |
|
---|
| 766 | /*********************************************************************************************************
|
---|
| 767 | ** Function name: sendMsg
|
---|
| 768 | ** Descriptions: send buf
|
---|
| 769 | *********************************************************************************************************/
|
---|
| 770 | INT8U MCP_CAN::sendMsg(INT8U txbid, INT32U id, INT8U len, INT8U *p_buf)
|
---|
| 771 | {
|
---|
| 772 | return sendMsg(txbid, id, len, p_buf, 0, 0);
|
---|
| 773 | }
|
---|
| 774 |
|
---|
| 775 |
|
---|
| 776 | /*********************************************************************************************************
|
---|
| 777 | ** Function name: readMsg
|
---|
| 778 | ** Descriptions: read message
|
---|
| 779 | *********************************************************************************************************/
|
---|
| 780 | INT8U MCP_CAN::readMsg(INT8U rxbid, INT32U *p_id, INT8U *p_len, INT8U *p_buf, INT8U *p_ext, INT8U *p_rtr)
|
---|
| 781 | {
|
---|
| 782 | INT8U stat, res;
|
---|
| 783 | CHECK_RXBID(rxbid);
|
---|
| 784 | INT8U stat_bit = (rxbid == 0)? MCP_STAT_RX0IF : MCP_STAT_RX1IF;
|
---|
| 785 | INT8U intf_bit = (rxbid == 0)? MCP_RX0IF : MCP_RX1IF;
|
---|
| 786 |
|
---|
| 787 | stat = mcp2515_readStatus();
|
---|
| 788 |
|
---|
| 789 | if ( stat & stat_bit )
|
---|
| 790 | {
|
---|
| 791 | mcp2515_read_canMsg(rxbid, p_id, p_len, p_buf, p_ext, p_rtr);
|
---|
| 792 | mcp2515_modifyRegister(MCP_CANINTF, intf_bit, 0);
|
---|
| 793 | res = CAN_OK;
|
---|
| 794 | }
|
---|
| 795 | else {
|
---|
| 796 | res = CAN_NOMSG;
|
---|
| 797 | }
|
---|
| 798 | return res;
|
---|
| 799 | }
|
---|
| 800 |
|
---|
| 801 | /*********************************************************************************************************
|
---|
| 802 | ** Function name: readMsgBuf
|
---|
| 803 | ** Descriptions: read message
|
---|
| 804 | *********************************************************************************************************/
|
---|
| 805 | INT8U MCP_CAN::readMsg(INT8U rxbid, INT32U *p_id, INT8U *p_len, INT8U *p_buf, INT8U *p_ext)
|
---|
| 806 | {
|
---|
| 807 | INT8U rtr;
|
---|
| 808 |
|
---|
| 809 | return readMsg(rxbid, p_id, p_len, p_buf, p_ext, &rtr);
|
---|
| 810 | }
|
---|
| 811 |
|
---|
| 812 | /*********************************************************************************************************
|
---|
| 813 | ** Function name: readMsgBuf
|
---|
| 814 | ** Descriptions: read message
|
---|
| 815 | *********************************************************************************************************/
|
---|
| 816 | INT8U MCP_CAN::readMsg(INT8U rxbid, INT32U *p_id, INT8U *p_len, INT8U *p_buf)
|
---|
| 817 | {
|
---|
| 818 | INT8U ext;
|
---|
| 819 | INT8U rtr;
|
---|
| 820 |
|
---|
| 821 | return readMsg(rxbid, p_id, p_len, p_buf, &ext, &rtr);
|
---|
| 822 | }
|
---|
| 823 |
|
---|
| 824 | /*********************************************************************************************************
|
---|
| 825 | ** Function name: readMsgBuf
|
---|
| 826 | ** Descriptions: read message
|
---|
| 827 | *********************************************************************************************************/
|
---|
| 828 | INT8U MCP_CAN::readMsg(INT8U rxbid, INT8U *p_len, INT8U *p_buf)
|
---|
| 829 | {
|
---|
| 830 | INT32U id;
|
---|
| 831 | INT8U ext;
|
---|
| 832 | INT8U rtr;
|
---|
| 833 |
|
---|
| 834 | return readMsg(rxbid, &id, p_len, p_buf, &ext, &rtr);
|
---|
| 835 | }
|
---|
| 836 |
|
---|
| 837 | /*********************************************************************************************************
|
---|
| 838 | ** Function name: checkReceive
|
---|
| 839 | ** Descriptions: check if got something
|
---|
| 840 | *********************************************************************************************************/
|
---|
| 841 | INT8U MCP_CAN::checkReceive(INT8U rxbid)
|
---|
| 842 | {
|
---|
| 843 | INT8U res;
|
---|
| 844 | CHECK_RXBID(rxbid);
|
---|
| 845 | res = mcp2515_readStatus(); /* RXnIF in Bit 1 and 0 */
|
---|
| 846 | if (rxbid == 0) {
|
---|
| 847 | if ( (res & MCP_STAT_RX0IF) == MCP_STAT_RX0IF) {
|
---|
| 848 | return CAN_MSGAVAIL;
|
---|
| 849 | }
|
---|
| 850 | }
|
---|
| 851 | else if (rxbid == 1) {
|
---|
| 852 | if ( (res & MCP_STAT_RX1IF) == MCP_STAT_RX1IF ) {
|
---|
| 853 | return CAN_MSGAVAIL;
|
---|
| 854 | }
|
---|
| 855 | }
|
---|
| 856 | return CAN_NOMSG;
|
---|
| 857 | }
|
---|
| 858 |
|
---|
| 859 | /*********************************************************************************************************
|
---|
| 860 | ** Function name: checkSend
|
---|
| 861 | ** Descriptions: check if snt msg
|
---|
| 862 | *********************************************************************************************************/
|
---|
| 863 | INT8U MCP_CAN::checkSend(INT8U txbid)
|
---|
| 864 | {
|
---|
| 865 | INT8U res;
|
---|
| 866 | INT8U txbx_ctrl[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
|
---|
| 867 |
|
---|
| 868 | CHECK_TXBID(txbid);
|
---|
| 869 |
|
---|
| 870 | res = mcp2515_readRegister(txbx_ctrl[txbid]);
|
---|
| 871 |
|
---|
| 872 | if ( (res & MCP_TXB_TXREQ_M) == MCP_TXB_TXREQ_M) {
|
---|
| 873 | return CAN_SENDWAIT;
|
---|
| 874 | }
|
---|
| 875 |
|
---|
| 876 | return CAN_NOSENDWAIT;
|
---|
| 877 | }
|
---|
| 878 |
|
---|
| 879 | /*********************************************************************************************************
|
---|
| 880 | ** Function name: checkError
|
---|
| 881 | ** Descriptions: if something error
|
---|
| 882 | *********************************************************************************************************/
|
---|
| 883 | INT8U MCP_CAN::checkError(void)
|
---|
| 884 | {
|
---|
| 885 | INT8U eflg = mcp2515_readRegister(MCP_EFLG);
|
---|
| 886 |
|
---|
| 887 | if ( eflg & MCP_EFLG_ERRORMASK )
|
---|
| 888 | {
|
---|
| 889 | return CAN_CTRLERROR;
|
---|
| 890 | }
|
---|
| 891 | else
|
---|
| 892 | {
|
---|
| 893 | return CAN_OK;
|
---|
| 894 | }
|
---|
| 895 | }
|
---|
| 896 |
|
---|
| 897 | /*********************************************************************************************************
|
---|
| 898 | END FILE
|
---|
| 899 | *********************************************************************************************************/
|
---|