mcp_can.cpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. /*
  2. mcp_can.cpp
  3. 2012 Copyright (c) Seeed Technology Inc. All right reserved.
  4. 2017 Copyright (c) Cory J. Fowler All Rights Reserved.
  5. Author: Loovee
  6. Contributor: Cory J. Fowler
  7. 2017-09-25
  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. This library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Lesser General Public License for more details.
  16. You should have received a copy of the GNU Lesser General Public
  17. License along with this library; if not, write to the Free Software
  18. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-
  19. 1301 USA
  20. */
  21. #include "mcp_can.h"
  22. #define spi_readwrite SPI.transfer
  23. #define spi_read() spi_readwrite(0x00)
  24. /*********************************************************************************************************
  25. ** Function name: mcp2515_reset
  26. ** Descriptions: Performs a software reset
  27. *********************************************************************************************************/
  28. void MCP_CAN::mcp2515_reset(void)
  29. {
  30. SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  31. MCP2515_SELECT();
  32. spi_readwrite(MCP_RESET);
  33. MCP2515_UNSELECT();
  34. SPI.endTransaction();
  35. delayMicroseconds(10);
  36. }
  37. /*********************************************************************************************************
  38. ** Function name: mcp2515_readRegister
  39. ** Descriptions: Read data register
  40. *********************************************************************************************************/
  41. INT8U MCP_CAN::mcp2515_readRegister(const INT8U address)
  42. {
  43. INT8U ret;
  44. SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  45. MCP2515_SELECT();
  46. spi_readwrite(MCP_READ);
  47. spi_readwrite(address);
  48. ret = spi_read();
  49. MCP2515_UNSELECT();
  50. SPI.endTransaction();
  51. return ret;
  52. }
  53. /*********************************************************************************************************
  54. ** Function name: mcp2515_readRegisterS
  55. ** Descriptions: Reads sucessive data registers
  56. *********************************************************************************************************/
  57. void MCP_CAN::mcp2515_readRegisterS(const INT8U address, INT8U values[], const INT8U n)
  58. {
  59. INT8U i;
  60. SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  61. MCP2515_SELECT();
  62. spi_readwrite(MCP_READ);
  63. spi_readwrite(address);
  64. // mcp2515 has auto-increment of address-pointer
  65. for (i=0; i<n; i++)
  66. values[i] = spi_read();
  67. MCP2515_UNSELECT();
  68. SPI.endTransaction();
  69. }
  70. /*********************************************************************************************************
  71. ** Function name: mcp2515_setRegister
  72. ** Descriptions: Sets data register
  73. *********************************************************************************************************/
  74. void MCP_CAN::mcp2515_setRegister(const INT8U address, const INT8U value)
  75. {
  76. SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  77. MCP2515_SELECT();
  78. spi_readwrite(MCP_WRITE);
  79. spi_readwrite(address);
  80. spi_readwrite(value);
  81. MCP2515_UNSELECT();
  82. SPI.endTransaction();
  83. }
  84. /*********************************************************************************************************
  85. ** Function name: mcp2515_setRegisterS
  86. ** Descriptions: Sets sucessive data registers
  87. *********************************************************************************************************/
  88. void MCP_CAN::mcp2515_setRegisterS(const INT8U address, const INT8U values[], const INT8U n)
  89. {
  90. INT8U i;
  91. SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  92. MCP2515_SELECT();
  93. spi_readwrite(MCP_WRITE);
  94. spi_readwrite(address);
  95. for (i=0; i<n; i++)
  96. spi_readwrite(values[i]);
  97. MCP2515_UNSELECT();
  98. SPI.endTransaction();
  99. }
  100. /*********************************************************************************************************
  101. ** Function name: mcp2515_modifyRegister
  102. ** Descriptions: Sets specific bits of a register
  103. *********************************************************************************************************/
  104. void MCP_CAN::mcp2515_modifyRegister(const INT8U address, const INT8U mask, const INT8U data)
  105. {
  106. SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  107. MCP2515_SELECT();
  108. spi_readwrite(MCP_BITMOD);
  109. spi_readwrite(address);
  110. spi_readwrite(mask);
  111. spi_readwrite(data);
  112. MCP2515_UNSELECT();
  113. SPI.endTransaction();
  114. }
  115. /*********************************************************************************************************
  116. ** Function name: mcp2515_readStatus
  117. ** Descriptions: Reads status register
  118. *********************************************************************************************************/
  119. INT8U MCP_CAN::mcp2515_readStatus(void)
  120. {
  121. INT8U i;
  122. SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  123. MCP2515_SELECT();
  124. spi_readwrite(MCP_READ_STATUS);
  125. i = spi_read();
  126. MCP2515_UNSELECT();
  127. SPI.endTransaction();
  128. return i;
  129. }
  130. /*********************************************************************************************************
  131. ** Function name: setMode
  132. ** Descriptions: Sets control mode
  133. *********************************************************************************************************/
  134. INT8U MCP_CAN::setMode(const INT8U opMode)
  135. {
  136. mcpMode = opMode;
  137. return mcp2515_setCANCTRL_Mode(mcpMode);
  138. }
  139. /*********************************************************************************************************
  140. ** Function name: mcp2515_setCANCTRL_Mode
  141. ** Descriptions: Set control mode
  142. *********************************************************************************************************/
  143. INT8U MCP_CAN::mcp2515_setCANCTRL_Mode(const INT8U newmode)
  144. {
  145. INT8U i;
  146. mcp2515_modifyRegister(MCP_CANCTRL, MODE_MASK, newmode);
  147. i = mcp2515_readRegister(MCP_CANCTRL);
  148. i &= MODE_MASK;
  149. if ( i == newmode )
  150. return MCP2515_OK;
  151. return MCP2515_FAIL;
  152. }
  153. /*********************************************************************************************************
  154. ** Function name: mcp2515_configRate
  155. ** Descriptions: Set baudrate
  156. *********************************************************************************************************/
  157. INT8U MCP_CAN::mcp2515_configRate(const INT8U canSpeed, const INT8U canClock)
  158. {
  159. INT8U set, cfg1, cfg2, cfg3;
  160. set = 1;
  161. switch (canClock)
  162. {
  163. case (MCP_8MHZ):
  164. switch (canSpeed)
  165. {
  166. case (CAN_5KBPS): // 5KBPS
  167. cfg1 = MCP_8MHz_5kBPS_CFG1;
  168. cfg2 = MCP_8MHz_5kBPS_CFG2;
  169. cfg3 = MCP_8MHz_5kBPS_CFG3;
  170. break;
  171. case (CAN_10KBPS): // 10KBPS
  172. cfg1 = MCP_8MHz_10kBPS_CFG1;
  173. cfg2 = MCP_8MHz_10kBPS_CFG2;
  174. cfg3 = MCP_8MHz_10kBPS_CFG3;
  175. break;
  176. case (CAN_20KBPS): // 20KBPS
  177. cfg1 = MCP_8MHz_20kBPS_CFG1;
  178. cfg2 = MCP_8MHz_20kBPS_CFG2;
  179. cfg3 = MCP_8MHz_20kBPS_CFG3;
  180. break;
  181. case (CAN_31K25BPS): // 31.25KBPS
  182. cfg1 = MCP_8MHz_31k25BPS_CFG1;
  183. cfg2 = MCP_8MHz_31k25BPS_CFG2;
  184. cfg3 = MCP_8MHz_31k25BPS_CFG3;
  185. break;
  186. case (CAN_33K3BPS): // 33.33KBPS
  187. cfg1 = MCP_8MHz_33k3BPS_CFG1;
  188. cfg2 = MCP_8MHz_33k3BPS_CFG2;
  189. cfg3 = MCP_8MHz_33k3BPS_CFG3;
  190. break;
  191. case (CAN_40KBPS): // 40Kbps
  192. cfg1 = MCP_8MHz_40kBPS_CFG1;
  193. cfg2 = MCP_8MHz_40kBPS_CFG2;
  194. cfg3 = MCP_8MHz_40kBPS_CFG3;
  195. break;
  196. case (CAN_50KBPS): // 50Kbps
  197. cfg1 = MCP_8MHz_50kBPS_CFG1;
  198. cfg2 = MCP_8MHz_50kBPS_CFG2;
  199. cfg3 = MCP_8MHz_50kBPS_CFG3;
  200. break;
  201. case (CAN_80KBPS): // 80Kbps
  202. cfg1 = MCP_8MHz_80kBPS_CFG1;
  203. cfg2 = MCP_8MHz_80kBPS_CFG2;
  204. cfg3 = MCP_8MHz_80kBPS_CFG3;
  205. break;
  206. case (CAN_100KBPS): // 100Kbps
  207. cfg1 = MCP_8MHz_100kBPS_CFG1;
  208. cfg2 = MCP_8MHz_100kBPS_CFG2;
  209. cfg3 = MCP_8MHz_100kBPS_CFG3;
  210. break;
  211. case (CAN_125KBPS): // 125Kbps
  212. cfg1 = MCP_8MHz_125kBPS_CFG1;
  213. cfg2 = MCP_8MHz_125kBPS_CFG2;
  214. cfg3 = MCP_8MHz_125kBPS_CFG3;
  215. break;
  216. case (CAN_200KBPS): // 200Kbps
  217. cfg1 = MCP_8MHz_200kBPS_CFG1;
  218. cfg2 = MCP_8MHz_200kBPS_CFG2;
  219. cfg3 = MCP_8MHz_200kBPS_CFG3;
  220. break;
  221. case (CAN_250KBPS): // 250Kbps
  222. cfg1 = MCP_8MHz_250kBPS_CFG1;
  223. cfg2 = MCP_8MHz_250kBPS_CFG2;
  224. cfg3 = MCP_8MHz_250kBPS_CFG3;
  225. break;
  226. case (CAN_500KBPS): // 500Kbps
  227. cfg1 = MCP_8MHz_500kBPS_CFG1;
  228. cfg2 = MCP_8MHz_500kBPS_CFG2;
  229. cfg3 = MCP_8MHz_500kBPS_CFG3;
  230. break;
  231. case (CAN_1000KBPS): // 1Mbps
  232. cfg1 = MCP_8MHz_1000kBPS_CFG1;
  233. cfg2 = MCP_8MHz_1000kBPS_CFG2;
  234. cfg3 = MCP_8MHz_1000kBPS_CFG3;
  235. break;
  236. default:
  237. set = 0;
  238. return MCP2515_FAIL;
  239. break;
  240. }
  241. break;
  242. case (MCP_16MHZ):
  243. switch (canSpeed)
  244. {
  245. case (CAN_5KBPS): // 5Kbps
  246. cfg1 = MCP_16MHz_5kBPS_CFG1;
  247. cfg2 = MCP_16MHz_5kBPS_CFG2;
  248. cfg3 = MCP_16MHz_5kBPS_CFG3;
  249. break;
  250. case (CAN_10KBPS): // 10Kbps
  251. cfg1 = MCP_16MHz_10kBPS_CFG1;
  252. cfg2 = MCP_16MHz_10kBPS_CFG2;
  253. cfg3 = MCP_16MHz_10kBPS_CFG3;
  254. break;
  255. case (CAN_20KBPS): // 20Kbps
  256. cfg1 = MCP_16MHz_20kBPS_CFG1;
  257. cfg2 = MCP_16MHz_20kBPS_CFG2;
  258. cfg3 = MCP_16MHz_20kBPS_CFG3;
  259. break;
  260. case (CAN_33K3BPS): // 20Kbps
  261. cfg1 = MCP_16MHz_33k3BPS_CFG1;
  262. cfg2 = MCP_16MHz_33k3BPS_CFG2;
  263. cfg3 = MCP_16MHz_33k3BPS_CFG3;
  264. break;
  265. case (CAN_40KBPS): // 40Kbps
  266. cfg1 = MCP_16MHz_40kBPS_CFG1;
  267. cfg2 = MCP_16MHz_40kBPS_CFG2;
  268. cfg3 = MCP_16MHz_40kBPS_CFG3;
  269. break;
  270. case (CAN_50KBPS): // 50Kbps
  271. cfg2 = MCP_16MHz_50kBPS_CFG2;
  272. cfg3 = MCP_16MHz_50kBPS_CFG3;
  273. break;
  274. case (CAN_80KBPS): // 80Kbps
  275. cfg1 = MCP_16MHz_80kBPS_CFG1;
  276. cfg2 = MCP_16MHz_80kBPS_CFG2;
  277. cfg3 = MCP_16MHz_80kBPS_CFG3;
  278. break;
  279. case (CAN_100KBPS): // 100Kbps
  280. cfg1 = MCP_16MHz_100kBPS_CFG1;
  281. cfg2 = MCP_16MHz_100kBPS_CFG2;
  282. cfg3 = MCP_16MHz_100kBPS_CFG3;
  283. break;
  284. case (CAN_125KBPS): // 125Kbps
  285. cfg1 = MCP_16MHz_125kBPS_CFG1;
  286. cfg2 = MCP_16MHz_125kBPS_CFG2;
  287. cfg3 = MCP_16MHz_125kBPS_CFG3;
  288. break;
  289. case (CAN_200KBPS): // 200Kbps
  290. cfg1 = MCP_16MHz_200kBPS_CFG1;
  291. cfg2 = MCP_16MHz_200kBPS_CFG2;
  292. cfg3 = MCP_16MHz_200kBPS_CFG3;
  293. break;
  294. case (CAN_250KBPS): // 250Kbps
  295. cfg1 = MCP_16MHz_250kBPS_CFG1;
  296. cfg2 = MCP_16MHz_250kBPS_CFG2;
  297. cfg3 = MCP_16MHz_250kBPS_CFG3;
  298. break;
  299. case (CAN_500KBPS): // 500Kbps
  300. cfg1 = MCP_16MHz_500kBPS_CFG1;
  301. cfg2 = MCP_16MHz_500kBPS_CFG2;
  302. cfg3 = MCP_16MHz_500kBPS_CFG3;
  303. break;
  304. case (CAN_1000KBPS): // 1Mbps
  305. cfg1 = MCP_16MHz_1000kBPS_CFG1;
  306. cfg2 = MCP_16MHz_1000kBPS_CFG2;
  307. cfg3 = MCP_16MHz_1000kBPS_CFG3;
  308. break;
  309. default:
  310. set = 0;
  311. return MCP2515_FAIL;
  312. break;
  313. }
  314. break;
  315. case (MCP_20MHZ):
  316. switch (canSpeed)
  317. {
  318. case (CAN_40KBPS): // 40Kbps
  319. cfg1 = MCP_20MHz_40kBPS_CFG1;
  320. cfg2 = MCP_20MHz_40kBPS_CFG2;
  321. cfg3 = MCP_20MHz_40kBPS_CFG3;
  322. break;
  323. case (CAN_50KBPS): // 50Kbps
  324. cfg1 = MCP_20MHz_50kBPS_CFG1;
  325. cfg2 = MCP_20MHz_50kBPS_CFG2;
  326. cfg3 = MCP_20MHz_50kBPS_CFG3;
  327. break;
  328. case (CAN_80KBPS): // 80Kbps
  329. cfg1 = MCP_20MHz_80kBPS_CFG1;
  330. cfg2 = MCP_20MHz_80kBPS_CFG2;
  331. cfg3 = MCP_20MHz_80kBPS_CFG3;
  332. break;
  333. case (CAN_100KBPS): // 100Kbps
  334. cfg1 = MCP_20MHz_100kBPS_CFG1;
  335. cfg2 = MCP_20MHz_100kBPS_CFG2;
  336. cfg3 = MCP_20MHz_100kBPS_CFG3;
  337. break;
  338. case (CAN_125KBPS): // 125Kbps
  339. cfg1 = MCP_20MHz_125kBPS_CFG1;
  340. cfg2 = MCP_20MHz_125kBPS_CFG2;
  341. cfg3 = MCP_20MHz_125kBPS_CFG3;
  342. break;
  343. case (CAN_200KBPS): // 200Kbps
  344. cfg1 = MCP_20MHz_200kBPS_CFG1;
  345. cfg2 = MCP_20MHz_200kBPS_CFG2;
  346. cfg3 = MCP_20MHz_200kBPS_CFG3;
  347. break;
  348. case (CAN_250KBPS): // 250Kbps
  349. cfg1 = MCP_20MHz_250kBPS_CFG1;
  350. cfg2 = MCP_20MHz_250kBPS_CFG2;
  351. cfg3 = MCP_20MHz_250kBPS_CFG3;
  352. break;
  353. case (CAN_500KBPS): // 500Kbps
  354. cfg1 = MCP_20MHz_500kBPS_CFG1;
  355. cfg2 = MCP_20MHz_500kBPS_CFG2;
  356. cfg3 = MCP_20MHz_500kBPS_CFG3;
  357. break;
  358. case (CAN_1000KBPS): // 1Mbps
  359. cfg1 = MCP_20MHz_1000kBPS_CFG1;
  360. cfg2 = MCP_20MHz_1000kBPS_CFG2;
  361. cfg3 = MCP_20MHz_1000kBPS_CFG3;
  362. break;
  363. default:
  364. set = 0;
  365. return MCP2515_FAIL;
  366. break;
  367. }
  368. break;
  369. default:
  370. set = 0;
  371. return MCP2515_FAIL;
  372. break;
  373. }
  374. if (set) {
  375. mcp2515_setRegister(MCP_CNF1, cfg1);
  376. mcp2515_setRegister(MCP_CNF2, cfg2);
  377. mcp2515_setRegister(MCP_CNF3, cfg3);
  378. return MCP2515_OK;
  379. }
  380. return MCP2515_FAIL;
  381. }
  382. /*********************************************************************************************************
  383. ** Function name: mcp2515_initCANBuffers
  384. ** Descriptions: Initialize Buffers, Masks, and Filters
  385. *********************************************************************************************************/
  386. void MCP_CAN::mcp2515_initCANBuffers(void)
  387. {
  388. INT8U i, a1, a2, a3;
  389. INT8U std = 0;
  390. INT8U ext = 1;
  391. INT32U ulMask = 0x00, ulFilt = 0x00;
  392. mcp2515_write_mf(MCP_RXM0SIDH, ext, ulMask); /*Set both masks to 0 */
  393. mcp2515_write_mf(MCP_RXM1SIDH, ext, ulMask); /*Mask register ignores ext bit */
  394. /* Set all filters to 0 */
  395. mcp2515_write_mf(MCP_RXF0SIDH, ext, ulFilt); /* RXB0: extended */
  396. mcp2515_write_mf(MCP_RXF1SIDH, std, ulFilt); /* RXB1: standard */
  397. mcp2515_write_mf(MCP_RXF2SIDH, ext, ulFilt); /* RXB2: extended */
  398. mcp2515_write_mf(MCP_RXF3SIDH, std, ulFilt); /* RXB3: standard */
  399. mcp2515_write_mf(MCP_RXF4SIDH, ext, ulFilt);
  400. mcp2515_write_mf(MCP_RXF5SIDH, std, ulFilt);
  401. /* Clear, deactivate the three */
  402. /* transmit buffers */
  403. /* TXBnCTRL -> TXBnD7 */
  404. a1 = MCP_TXB0CTRL;
  405. a2 = MCP_TXB1CTRL;
  406. a3 = MCP_TXB2CTRL;
  407. for (i = 0; i < 14; i++) { /* in-buffer loop */
  408. mcp2515_setRegister(a1, 0);
  409. mcp2515_setRegister(a2, 0);
  410. mcp2515_setRegister(a3, 0);
  411. a1++;
  412. a2++;
  413. a3++;
  414. }
  415. mcp2515_setRegister(MCP_RXB0CTRL, 0);
  416. mcp2515_setRegister(MCP_RXB1CTRL, 0);
  417. }
  418. /*********************************************************************************************************
  419. ** Function name: mcp2515_init
  420. ** Descriptions: Initialize the controller
  421. *********************************************************************************************************/
  422. INT8U MCP_CAN::mcp2515_init(const INT8U canIDMode, const INT8U canSpeed, const INT8U canClock)
  423. {
  424. INT8U res;
  425. mcp2515_reset();
  426. mcpMode = MCP_LOOPBACK;
  427. res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
  428. if(res > 0)
  429. {
  430. #if DEBUG_MODE
  431. Serial.print("Entering Configuration Mode Failure...\r\n");
  432. #endif
  433. return res;
  434. }
  435. #if DEBUG_MODE
  436. Serial.print("Entering Configuration Mode Successful!\r\n");
  437. #endif
  438. // Set Baudrate
  439. if(mcp2515_configRate(canSpeed, canClock))
  440. {
  441. #if DEBUG_MODE
  442. Serial.print("Setting Baudrate Failure...\r\n");
  443. #endif
  444. return res;
  445. }
  446. #if DEBUG_MODE
  447. Serial.print("Setting Baudrate Successful!\r\n");
  448. #endif
  449. if ( res == MCP2515_OK ) {
  450. /* init canbuffers */
  451. mcp2515_initCANBuffers();
  452. /* interrupt mode */
  453. mcp2515_setRegister(MCP_CANINTE, MCP_RX0IF | MCP_RX1IF);
  454. //Sets BF pins as GPO
  455. mcp2515_setRegister(MCP_BFPCTRL,MCP_BxBFS_MASK | MCP_BxBFE_MASK);
  456. //Sets RTS pins as GPI
  457. mcp2515_setRegister(MCP_TXRTSCTRL,0x00);
  458. switch(canIDMode)
  459. {
  460. case (MCP_ANY):
  461. mcp2515_modifyRegister(MCP_RXB0CTRL,
  462. MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
  463. MCP_RXB_RX_ANY | MCP_RXB_BUKT_MASK);
  464. mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
  465. MCP_RXB_RX_ANY);
  466. break;
  467. /* The followingn two functions of the MCP2515 do not work, there is a bug in the silicon.
  468. case (MCP_STD):
  469. mcp2515_modifyRegister(MCP_RXB0CTRL,
  470. MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
  471. MCP_RXB_RX_STD | MCP_RXB_BUKT_MASK );
  472. mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
  473. MCP_RXB_RX_STD);
  474. break;
  475. case (MCP_EXT):
  476. mcp2515_modifyRegister(MCP_RXB0CTRL,
  477. MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
  478. MCP_RXB_RX_EXT | MCP_RXB_BUKT_MASK );
  479. mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
  480. MCP_RXB_RX_EXT);
  481. break;
  482. */
  483. case (MCP_STDEXT):
  484. mcp2515_modifyRegister(MCP_RXB0CTRL,
  485. MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
  486. MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK );
  487. mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
  488. MCP_RXB_RX_STDEXT);
  489. break;
  490. default:
  491. #if DEBUG_MODE
  492. Serial.print("`Setting ID Mode Failure...\r\n");
  493. #endif
  494. return MCP2515_FAIL;
  495. break;
  496. }
  497. res = mcp2515_setCANCTRL_Mode(mcpMode);
  498. if(res)
  499. {
  500. #if DEBUG_MODE
  501. Serial.print("Returning to Previous Mode Failure...\r\n");
  502. #endif
  503. return res;
  504. }
  505. }
  506. return res;
  507. }
  508. /*********************************************************************************************************
  509. ** Function name: mcp2515_write_id
  510. ** Descriptions: Write CAN ID
  511. *********************************************************************************************************/
  512. void MCP_CAN::mcp2515_write_id( const INT8U mcp_addr, const INT8U ext, const INT32U id )
  513. {
  514. uint16_t canid;
  515. INT8U tbufdata[4];
  516. canid = (uint16_t)(id & 0x0FFFF);
  517. if ( ext == 1)
  518. {
  519. tbufdata[MCP_EID0] = (INT8U) (canid & 0xFF);
  520. tbufdata[MCP_EID8] = (INT8U) (canid >> 8);
  521. canid = (uint16_t)(id >> 16);
  522. tbufdata[MCP_SIDL] = (INT8U) (canid & 0x03);
  523. tbufdata[MCP_SIDL] += (INT8U) ((canid & 0x1C) << 3);
  524. tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M;
  525. tbufdata[MCP_SIDH] = (INT8U) (canid >> 5 );
  526. }
  527. else
  528. {
  529. tbufdata[MCP_SIDH] = (INT8U) (canid >> 3 );
  530. tbufdata[MCP_SIDL] = (INT8U) ((canid & 0x07 ) << 5);
  531. tbufdata[MCP_EID0] = 0;
  532. tbufdata[MCP_EID8] = 0;
  533. }
  534. mcp2515_setRegisterS( mcp_addr, tbufdata, 4 );
  535. }
  536. /*********************************************************************************************************
  537. ** Function name: mcp2515_write_mf
  538. ** Descriptions: Write Masks and Filters
  539. *********************************************************************************************************/
  540. void MCP_CAN::mcp2515_write_mf( const INT8U mcp_addr, const INT8U ext, const INT32U id )
  541. {
  542. uint16_t canid;
  543. INT8U tbufdata[4];
  544. canid = (uint16_t)(id & 0x0FFFF);
  545. if ( ext == 1)
  546. {
  547. tbufdata[MCP_EID0] = (INT8U) (canid & 0xFF);
  548. tbufdata[MCP_EID8] = (INT8U) (canid >> 8);
  549. canid = (uint16_t)(id >> 16);
  550. tbufdata[MCP_SIDL] = (INT8U) (canid & 0x03);
  551. tbufdata[MCP_SIDL] += (INT8U) ((canid & 0x1C) << 3);
  552. tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M;
  553. tbufdata[MCP_SIDH] = (INT8U) (canid >> 5 );
  554. }
  555. else
  556. {
  557. tbufdata[MCP_EID0] = (INT8U) (canid & 0xFF);
  558. tbufdata[MCP_EID8] = (INT8U) (canid >> 8);
  559. canid = (uint16_t)(id >> 16);
  560. tbufdata[MCP_SIDL] = (INT8U) ((canid & 0x07) << 5);
  561. tbufdata[MCP_SIDH] = (INT8U) (canid >> 3 );
  562. }
  563. mcp2515_setRegisterS( mcp_addr, tbufdata, 4 );
  564. }
  565. /*********************************************************************************************************
  566. ** Function name: mcp2515_read_id
  567. ** Descriptions: Read CAN ID
  568. *********************************************************************************************************/
  569. void MCP_CAN::mcp2515_read_id( const INT8U mcp_addr, INT8U* ext, INT32U* id )
  570. {
  571. INT8U tbufdata[4];
  572. *ext = 0;
  573. *id = 0;
  574. mcp2515_readRegisterS( mcp_addr, tbufdata, 4 );
  575. *id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
  576. if ( (tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M )
  577. {
  578. /* extended id */
  579. *id = (*id<<2) + (tbufdata[MCP_SIDL] & 0x03);
  580. *id = (*id<<8) + tbufdata[MCP_EID8];
  581. *id = (*id<<8) + tbufdata[MCP_EID0];
  582. *ext = 1;
  583. }
  584. }
  585. /*********************************************************************************************************
  586. ** Function name: mcp2515_write_canMsg
  587. ** Descriptions: Write message
  588. *********************************************************************************************************/
  589. void MCP_CAN::mcp2515_write_canMsg( const INT8U buffer_sidh_addr)
  590. {
  591. INT8U mcp_addr;
  592. mcp_addr = buffer_sidh_addr;
  593. mcp2515_setRegisterS(mcp_addr+5, m_nDta, m_nDlc ); /* write data bytes */
  594. if ( m_nRtr == 1) /* if RTR set bit in byte */
  595. m_nDlc |= MCP_RTR_MASK;
  596. mcp2515_setRegister((mcp_addr+4), m_nDlc ); /* write the RTR and DLC */
  597. mcp2515_write_id(mcp_addr, m_nExtFlg, m_nID ); /* write CAN id */
  598. }
  599. /*********************************************************************************************************
  600. ** Function name: mcp2515_read_canMsg
  601. ** Descriptions: Read message
  602. *********************************************************************************************************/
  603. void MCP_CAN::mcp2515_read_canMsg( const INT8U buffer_sidh_addr) /* read can msg */
  604. {
  605. INT8U mcp_addr, ctrl;
  606. mcp_addr = buffer_sidh_addr;
  607. mcp2515_read_id( mcp_addr, &m_nExtFlg,&m_nID );
  608. ctrl = mcp2515_readRegister( mcp_addr-1 );
  609. m_nDlc = mcp2515_readRegister( mcp_addr+4 );
  610. if (ctrl & 0x08)
  611. m_nRtr = 1;
  612. else
  613. m_nRtr = 0;
  614. m_nDlc &= MCP_DLC_MASK;
  615. mcp2515_readRegisterS( mcp_addr+5, &(m_nDta[0]), m_nDlc );
  616. }
  617. /*********************************************************************************************************
  618. ** Function name: mcp2515_getNextFreeTXBuf
  619. ** Descriptions: Send message
  620. *********************************************************************************************************/
  621. INT8U MCP_CAN::mcp2515_getNextFreeTXBuf(INT8U *txbuf_n) /* get Next free txbuf */
  622. {
  623. INT8U res, i, ctrlval;
  624. INT8U ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
  625. res = MCP_ALLTXBUSY;
  626. *txbuf_n = 0x00;
  627. /* check all 3 TX-Buffers */
  628. for (i=0; i<MCP_N_TXBUFFERS; i++) {
  629. ctrlval = mcp2515_readRegister( ctrlregs[i] );
  630. if ( (ctrlval & MCP_TXB_TXREQ_M) == 0 ) {
  631. *txbuf_n = ctrlregs[i]+1; /* return SIDH-address of Buffer*/
  632. res = MCP2515_OK;
  633. return res; /* ! function exit */
  634. }
  635. }
  636. return res;
  637. }
  638. /*********************************************************************************************************
  639. ** Function name: MCP_CAN
  640. ** Descriptions: Public function to declare CAN class and the /CS pin.
  641. *********************************************************************************************************/
  642. MCP_CAN::MCP_CAN(INT8U _CS)
  643. {
  644. MCPCS = _CS;
  645. MCP2515_UNSELECT();
  646. pinMode(MCPCS, OUTPUT);
  647. }
  648. /*********************************************************************************************************
  649. ** Function name: begin
  650. ** Descriptions: Public function to declare controller initialization parameters.
  651. *********************************************************************************************************/
  652. //static inline void initSS() { pinMode(SPI_CS, OUTPUT); }
  653. //static inline void setSS() { digitalWrite(SPI_CS, LOW); }
  654. //static inline void resetSS() { digitalWrite(SPI_CS, HIGH); }
  655. /*void MCP_CAN::setSS() {
  656. Serial.print(" Set Low ");
  657. digitalWrite(8, LOW);
  658. }
  659. void MCP_CAN::resetSS() {
  660. digitalWrite(8, HIGH);
  661. }
  662. */
  663. INT8U MCP_CAN::begin(INT8U idmodeset, INT8U speedset, INT8U clockset)
  664. {
  665. INT8U res;
  666. SPI.begin();
  667. setSS();
  668. res = mcp2515_init(idmodeset, speedset, clockset);
  669. resetSS();
  670. if (res == MCP2515_OK)
  671. return CAN_OK;
  672. return CAN_FAILINIT;
  673. }
  674. /*********************************************************************************************************
  675. ** Function name: init_Mask
  676. ** Descriptions: Public function to set mask(s).
  677. *********************************************************************************************************/
  678. INT8U MCP_CAN::init_Mask(INT8U num, INT8U ext, INT32U ulData)
  679. {
  680. INT8U res = MCP2515_OK;
  681. #if DEBUG_MODE
  682. Serial.print("Starting to Set Mask!\r\n");
  683. #endif
  684. res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
  685. if(res > 0){
  686. #if DEBUG_MODE
  687. Serial.print("Entering Configuration Mode Failure...\r\n");
  688. #endif
  689. return res;
  690. }
  691. if (num == 0){
  692. mcp2515_write_mf(MCP_RXM0SIDH, ext, ulData);
  693. }
  694. else if(num == 1){
  695. mcp2515_write_mf(MCP_RXM1SIDH, ext, ulData);
  696. }
  697. else res = MCP2515_FAIL;
  698. res = mcp2515_setCANCTRL_Mode(mcpMode);
  699. if(res > 0){
  700. #if DEBUG_MODE
  701. Serial.print("Entering Previous Mode Failure...\r\nSetting Mask Failure...\r\n");
  702. #endif
  703. return res;
  704. }
  705. #if DEBUG_MODE
  706. Serial.print("Setting Mask Successful!\r\n");
  707. #endif
  708. return res;
  709. }
  710. /*********************************************************************************************************
  711. ** Function name: init_Mask
  712. ** Descriptions: Public function to set mask(s).
  713. *********************************************************************************************************/
  714. INT8U MCP_CAN::init_Mask(INT8U num, INT32U ulData)
  715. {
  716. INT8U res = MCP2515_OK;
  717. INT8U ext = 0;
  718. #if DEBUG_MODE
  719. Serial.print("Starting to Set Mask!\r\n");
  720. #endif
  721. res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
  722. if(res > 0){
  723. #if DEBUG_MODE
  724. Serial.print("Entering Configuration Mode Failure...\r\n");
  725. #endif
  726. return res;
  727. }
  728. if((ulData & 0x80000000) == 0x80000000)
  729. ext = 1;
  730. if (num == 0){
  731. mcp2515_write_mf(MCP_RXM0SIDH, ext, ulData);
  732. }
  733. else if(num == 1){
  734. mcp2515_write_mf(MCP_RXM1SIDH, ext, ulData);
  735. }
  736. else res = MCP2515_FAIL;
  737. res = mcp2515_setCANCTRL_Mode(mcpMode);
  738. if(res > 0){
  739. #if DEBUG_MODE
  740. Serial.print("Entering Previous Mode Failure...\r\nSetting Mask Failure...\r\n");
  741. #endif
  742. return res;
  743. }
  744. #if DEBUG_MODE
  745. Serial.print("Setting Mask Successful!\r\n");
  746. #endif
  747. return res;
  748. }
  749. /*********************************************************************************************************
  750. ** Function name: init_Filt
  751. ** Descriptions: Public function to set filter(s).
  752. *********************************************************************************************************/
  753. INT8U MCP_CAN::init_Filt(INT8U num, INT8U ext, INT32U ulData)
  754. {
  755. INT8U res = MCP2515_OK;
  756. #if DEBUG_MODE
  757. Serial.print("Starting to Set Filter!\r\n");
  758. #endif
  759. res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
  760. if(res > 0)
  761. {
  762. #if DEBUG_MODE
  763. Serial.print("Enter Configuration Mode Failure...\r\n");
  764. #endif
  765. return res;
  766. }
  767. switch( num )
  768. {
  769. case 0:
  770. mcp2515_write_mf(MCP_RXF0SIDH, ext, ulData);
  771. break;
  772. case 1:
  773. mcp2515_write_mf(MCP_RXF1SIDH, ext, ulData);
  774. break;
  775. case 2:
  776. mcp2515_write_mf(MCP_RXF2SIDH, ext, ulData);
  777. break;
  778. case 3:
  779. mcp2515_write_mf(MCP_RXF3SIDH, ext, ulData);
  780. break;
  781. case 4:
  782. mcp2515_write_mf(MCP_RXF4SIDH, ext, ulData);
  783. break;
  784. case 5:
  785. mcp2515_write_mf(MCP_RXF5SIDH, ext, ulData);
  786. break;
  787. default:
  788. res = MCP2515_FAIL;
  789. }
  790. res = mcp2515_setCANCTRL_Mode(mcpMode);
  791. if(res > 0)
  792. {
  793. #if DEBUG_MODE
  794. Serial.print("Entering Previous Mode Failure...\r\nSetting Filter Failure...\r\n");
  795. #endif
  796. return res;
  797. }
  798. #if DEBUG_MODE
  799. Serial.print("Setting Filter Successfull!\r\n");
  800. #endif
  801. return res;
  802. }
  803. /*********************************************************************************************************
  804. ** Function name: init_Filt
  805. ** Descriptions: Public function to set filter(s).
  806. *********************************************************************************************************/
  807. INT8U MCP_CAN::init_Filt(INT8U num, INT32U ulData)
  808. {
  809. INT8U res = MCP2515_OK;
  810. INT8U ext = 0;
  811. #if DEBUG_MODE
  812. Serial.print("Starting to Set Filter!\r\n");
  813. #endif
  814. res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
  815. if(res > 0)
  816. {
  817. #if DEBUG_MODE
  818. Serial.print("Enter Configuration Mode Failure...\r\n");
  819. #endif
  820. return res;
  821. }
  822. if((ulData & 0x80000000) == 0x80000000)
  823. ext = 1;
  824. switch( num )
  825. {
  826. case 0:
  827. mcp2515_write_mf(MCP_RXF0SIDH, ext, ulData);
  828. break;
  829. case 1:
  830. mcp2515_write_mf(MCP_RXF1SIDH, ext, ulData);
  831. break;
  832. case 2:
  833. mcp2515_write_mf(MCP_RXF2SIDH, ext, ulData);
  834. break;
  835. case 3:
  836. mcp2515_write_mf(MCP_RXF3SIDH, ext, ulData);
  837. break;
  838. case 4:
  839. mcp2515_write_mf(MCP_RXF4SIDH, ext, ulData);
  840. break;
  841. case 5:
  842. mcp2515_write_mf(MCP_RXF5SIDH, ext, ulData);
  843. break;
  844. default:
  845. res = MCP2515_FAIL;
  846. }
  847. res = mcp2515_setCANCTRL_Mode(mcpMode);
  848. if(res > 0)
  849. {
  850. #if DEBUG_MODE
  851. Serial.print("Entering Previous Mode Failure...\r\nSetting Filter Failure...\r\n");
  852. #endif
  853. return res;
  854. }
  855. #if DEBUG_MODE
  856. Serial.print("Setting Filter Successfull!\r\n");
  857. #endif
  858. return res;
  859. }
  860. /*********************************************************************************************************
  861. ** Function name: setMsg
  862. ** Descriptions: Set can message, such as dlc, id, dta[] and so on
  863. *********************************************************************************************************/
  864. INT8U MCP_CAN::setMsg(INT32U id, INT8U rtr, INT8U ext, INT8U len, INT8U *pData)
  865. {
  866. int i = 0;
  867. m_nID = id;
  868. m_nRtr = rtr;
  869. m_nExtFlg = ext;
  870. m_nDlc = len;
  871. for(i = 0; i<MAX_CHAR_IN_MESSAGE; i++)
  872. m_nDta[i] = *(pData+i);
  873. return MCP2515_OK;
  874. }
  875. /*********************************************************************************************************
  876. ** Function name: clearMsg
  877. ** Descriptions: Set all messages to zero
  878. *********************************************************************************************************/
  879. INT8U MCP_CAN::clearMsg()
  880. {
  881. m_nID = 0;
  882. m_nDlc = 0;
  883. m_nExtFlg = 0;
  884. m_nRtr = 0;
  885. m_nfilhit = 0;
  886. for(int i = 0; i<m_nDlc; i++ )
  887. m_nDta[i] = 0x00;
  888. return MCP2515_OK;
  889. }
  890. /*********************************************************************************************************
  891. ** Function name: sendMsg
  892. ** Descriptions: Send message
  893. *********************************************************************************************************/
  894. INT8U MCP_CAN::sendMsg()
  895. {
  896. INT8U res, res1, txbuf_n;
  897. uint16_t uiTimeOut = 0;
  898. do {
  899. res = mcp2515_getNextFreeTXBuf(&txbuf_n); /* info = addr. */
  900. uiTimeOut++;
  901. } while (res == MCP_ALLTXBUSY && (uiTimeOut < TIMEOUTVALUE));
  902. if(uiTimeOut == TIMEOUTVALUE)
  903. {
  904. return CAN_GETTXBFTIMEOUT; /* get tx buff time out */
  905. }
  906. uiTimeOut = 0;
  907. mcp2515_write_canMsg( txbuf_n);
  908. mcp2515_modifyRegister( txbuf_n-1 , MCP_TXB_TXREQ_M, MCP_TXB_TXREQ_M );
  909. do
  910. {
  911. uiTimeOut++;
  912. res1 = mcp2515_readRegister(txbuf_n-1); /* read send buff ctrl reg */
  913. res1 = res1 & 0x08;
  914. } while (res1 && (uiTimeOut < TIMEOUTVALUE));
  915. if(uiTimeOut == TIMEOUTVALUE) /* send msg timeout */
  916. return CAN_SENDMSGTIMEOUT;
  917. return CAN_OK;
  918. }
  919. /*********************************************************************************************************
  920. ** Function name: sendMsgBuf
  921. ** Descriptions: Send message to transmitt buffer
  922. *********************************************************************************************************/
  923. INT8U MCP_CAN::sendMsgBuf(INT32U id, INT8U ext, INT8U len, INT8U *buf)
  924. {
  925. INT8U res;
  926. setMsg(id, 0, ext, len, buf);
  927. res = sendMsg();
  928. return res;
  929. }
  930. /*********************************************************************************************************
  931. ** Function name: sendMsgBuf
  932. ** Descriptions: Send message to transmitt buffer
  933. *********************************************************************************************************/
  934. INT8U MCP_CAN::sendMsgBuf(INT32U id, INT8U len, INT8U *buf)
  935. {
  936. INT8U ext = 0, rtr = 0;
  937. INT8U res;
  938. if((id & 0x80000000) == 0x80000000)
  939. ext = 1;
  940. if((id & 0x40000000) == 0x40000000)
  941. rtr = 1;
  942. setMsg(id, rtr, ext, len, buf);
  943. res = sendMsg();
  944. return res;
  945. }
  946. /*********************************************************************************************************
  947. ** Function name: readMsg
  948. ** Descriptions: Read message
  949. *********************************************************************************************************/
  950. INT8U MCP_CAN::readMsg()
  951. {
  952. INT8U stat, res;
  953. stat = mcp2515_readStatus();
  954. if ( stat & MCP_STAT_RX0IF ) /* Msg in Buffer 0 */
  955. {
  956. mcp2515_read_canMsg( MCP_RXBUF_0);
  957. mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
  958. res = CAN_OK;
  959. }
  960. else if ( stat & MCP_STAT_RX1IF ) /* Msg in Buffer 1 */
  961. {
  962. mcp2515_read_canMsg( MCP_RXBUF_1);
  963. mcp2515_modifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
  964. res = CAN_OK;
  965. }
  966. else
  967. res = CAN_NOMSG;
  968. return res;
  969. }
  970. /*********************************************************************************************************
  971. ** Function name: readMsgBuf
  972. ** Descriptions: Public function, Reads message from receive buffer.
  973. *********************************************************************************************************/
  974. INT8U MCP_CAN::readMsgBuf(INT32U *id, INT8U *ext, INT8U *len, INT8U buf[])
  975. {
  976. if(readMsg() == CAN_NOMSG)
  977. return CAN_NOMSG;
  978. *id = m_nID;
  979. *len = m_nDlc;
  980. *ext = m_nExtFlg;
  981. for(int i = 0; i<m_nDlc; i++)
  982. buf[i] = m_nDta[i];
  983. return CAN_OK;
  984. }
  985. /*********************************************************************************************************
  986. ** Function name: readMsgBuf
  987. ** Descriptions: Public function, Reads message from receive buffer.
  988. *********************************************************************************************************/
  989. INT8U MCP_CAN::readMsgBuf(INT32U *id, INT8U *len, INT8U buf[])
  990. {
  991. if(readMsg() == CAN_NOMSG)
  992. return CAN_NOMSG;
  993. if (m_nExtFlg)
  994. m_nID |= 0x80000000;
  995. if (m_nRtr)
  996. m_nID |= 0x40000000;
  997. *id = m_nID;
  998. *len = m_nDlc;
  999. for(int i = 0; i<m_nDlc; i++)
  1000. buf[i] = m_nDta[i];
  1001. return CAN_OK;
  1002. }
  1003. /*********************************************************************************************************
  1004. ** Function name: checkReceive
  1005. ** Descriptions: Public function, Checks for received data. (Used if not using the interrupt output)
  1006. *********************************************************************************************************/
  1007. INT8U MCP_CAN::checkReceive(void)
  1008. {
  1009. INT8U res;
  1010. res = mcp2515_readStatus(); /* RXnIF in Bit 1 and 0 */
  1011. if ( res & MCP_STAT_RXIF_MASK )
  1012. return CAN_MSGAVAIL;
  1013. else
  1014. return CAN_NOMSG;
  1015. }
  1016. /*********************************************************************************************************
  1017. ** Function name: checkError
  1018. ** Descriptions: Public function, Returns error register data.
  1019. *********************************************************************************************************/
  1020. INT8U MCP_CAN::checkError(void)
  1021. {
  1022. INT8U eflg = mcp2515_readRegister(MCP_EFLG);
  1023. if ( eflg & MCP_EFLG_ERRORMASK )
  1024. return CAN_CTRLERROR;
  1025. else
  1026. return CAN_OK;
  1027. }
  1028. /*********************************************************************************************************
  1029. ** Function name: getError
  1030. ** Descriptions: Returns error register value.
  1031. *********************************************************************************************************/
  1032. INT8U MCP_CAN::getError(void)
  1033. {
  1034. return mcp2515_readRegister(MCP_EFLG);
  1035. }
  1036. /*********************************************************************************************************
  1037. ** Function name: mcp2515_errorCountRX
  1038. ** Descriptions: Returns REC register value
  1039. *********************************************************************************************************/
  1040. INT8U MCP_CAN::errorCountRX(void)
  1041. {
  1042. return mcp2515_readRegister(MCP_REC);
  1043. }
  1044. /*********************************************************************************************************
  1045. ** Function name: mcp2515_errorCountTX
  1046. ** Descriptions: Returns TEC register value
  1047. *********************************************************************************************************/
  1048. INT8U MCP_CAN::errorCountTX(void)
  1049. {
  1050. return mcp2515_readRegister(MCP_TEC);
  1051. }
  1052. /*********************************************************************************************************
  1053. ** Function name: mcp2515_enOneShotTX
  1054. ** Descriptions: Enables one shot transmission mode
  1055. *********************************************************************************************************/
  1056. INT8U MCP_CAN::enOneShotTX(void)
  1057. {
  1058. mcp2515_modifyRegister(MCP_CANCTRL, MODE_ONESHOT, MODE_ONESHOT);
  1059. if((mcp2515_readRegister(MCP_CANCTRL) & MODE_ONESHOT) != MODE_ONESHOT)
  1060. return CAN_FAIL;
  1061. else
  1062. return CAN_OK;
  1063. }
  1064. /*********************************************************************************************************
  1065. ** Function name: mcp2515_disOneShotTX
  1066. ** Descriptions: Disables one shot transmission mode
  1067. *********************************************************************************************************/
  1068. INT8U MCP_CAN::disOneShotTX(void)
  1069. {
  1070. mcp2515_modifyRegister(MCP_CANCTRL, MODE_ONESHOT, 0);
  1071. if((mcp2515_readRegister(MCP_CANCTRL) & MODE_ONESHOT) != 0)
  1072. return CAN_FAIL;
  1073. else
  1074. return CAN_OK;
  1075. }
  1076. /*********************************************************************************************************
  1077. ** Function name: mcp2515_abortTX
  1078. ** Descriptions: Aborts any queued transmissions
  1079. *********************************************************************************************************/
  1080. INT8U MCP_CAN::abortTX(void)
  1081. {
  1082. mcp2515_modifyRegister(MCP_CANCTRL, ABORT_TX, ABORT_TX);
  1083. // Maybe check to see if the TX buffer transmission request bits are cleared instead?
  1084. if((mcp2515_readRegister(MCP_CANCTRL) & ABORT_TX) != ABORT_TX)
  1085. return CAN_FAIL;
  1086. else
  1087. return CAN_OK;
  1088. }
  1089. /*********************************************************************************************************
  1090. ** Function name: setGPO
  1091. ** Descriptions: Public function, Checks for r
  1092. *********************************************************************************************************/
  1093. INT8U MCP_CAN::setGPO(INT8U data)
  1094. {
  1095. mcp2515_modifyRegister(MCP_BFPCTRL, MCP_BxBFS_MASK, (data<<4));
  1096. return 0;
  1097. }
  1098. /*********************************************************************************************************
  1099. ** Function name: getGPI
  1100. ** Descriptions: Public function, Checks for r
  1101. *********************************************************************************************************/
  1102. INT8U MCP_CAN::getGPI(void)
  1103. {
  1104. INT8U res;
  1105. res = mcp2515_readRegister(MCP_TXRTSCTRL) & MCP_BxRTS_MASK;
  1106. return (res >> 3);
  1107. }
  1108. /*********************************************************************************************************
  1109. END FILE
  1110. *********************************************************************************************************/