ECAN.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. /*********************************************************************
  2. *
  3. * ECAN C Library Source Code
  4. *
  5. *********************************************************************
  6. * FileName: ECAN.C
  7. * Dependencies: p18cxxx.h/pic18.h, ECAN.h
  8. * Processor: PIC18CXX8X
  9. * Compiler: Microchip C 2.10.06 or higher
  10. * Company: Microchip Technology, Inc.
  11. *
  12. * Software License Agreement
  13. *
  14. * The software supplied herewith by Microchip Technology Incorporated
  15. * (the “Company”) for its PICmicro® Microcontroller is intended and
  16. * supplied to you, the Company’s customer, for use solely and
  17. * exclusively on Microchip PICmicro Microcontroller products. The
  18. * software is owned by the Company and/or its supplier, and is
  19. * protected under applicable copyright laws. All rights are reserved.
  20. * Any use in violation of the foregoing restrictions may subject the
  21. * user to criminal sanctions under applicable laws, as well as to
  22. * civil liability for the breach of the terms and conditions of this
  23. * license.
  24. *
  25. * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
  26. * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
  27. * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  28. * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
  29. * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
  30. * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
  31. *
  32. * Author Date Comment
  33. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  34. * Caio Gubel 5/5/03 ECAN Version 1.0 - Initial Release
  35. * Nilesh R. 7/22/03 Improved.
  36. ********************************************************************/
  37. #include "ecan.h"
  38. #include "BMS_Slave.h"
  39. void _CANIDToRegs(BYTE* ptr,
  40. unsigned long val,
  41. BYTE type);
  42. void _RegsToCANID(BYTE* ptr,
  43. unsigned long *val,
  44. BYTE type);
  45. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || \
  46. (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_FIXED) && (ECAN_FUNC_MODE_VAL == ECAN_MODE_2) )
  47. static BYTE* _ECANPointBuffer(BYTE b);
  48. #endif
  49. BYTE_VAL _ECANRxFilterHitInfo;
  50. #define _SetStdRXFnValue(f, val) \
  51. ##f##SIDH = (long)ECAN_##f##_VAL >> 3L; \
  52. ##f##SIDL = (long)ECAN_##f##_VAL >> 5L
  53. #define _SetXtdRXFnValue(f, val) \
  54. ##f##SIDH = (long)ECAN_##f##_VAL >> 21L; \
  55. ##f##SIDL = (((long)ECAN_##f##_VAL >> 13L) & 0xe0) | \
  56. ((long)(ECAN_##f##_VAL) & 0x03L) | \
  57. 0x08; \
  58. ##f##EIDH = (long)ECAN_##f##_VAL >> 8L; \
  59. ##f##EIDL = ECAN_##f##_VAL;
  60. #define _SetStdRXMnValue(m, val) \
  61. RXM##m##SIDH = (long)ECAN_RXM##m##_VAL >> 3L; \
  62. RXM##m##SIDL = (long)ECAN_RXM##m##_VAL >> 5L
  63. #define _SetXtdRXMnValue(m, val) \
  64. RXM##m##SIDH = (long)ECAN_RXM##m##_VAL >> 21L; \
  65. RXM##m##SIDL = (((long)ECAN_RXM##m##_VAL >> 13L) & 0xe0) | \
  66. ((long)(ECAN_RXM##m##_VAL) & 0x03L);\
  67. RXM##m##EIDH = (long)ECAN_RXM##m##_VAL >> 8L;\
  68. RXM##m##EIDL = ECAN_RXM##m##_VAL;
  69. #define RXF0 0
  70. #define RXF1 1
  71. #define RXF2 2
  72. #define RXF3 3
  73. #define RXF4 4
  74. #define RXF5 5
  75. #define RXF6 6
  76. #define RXF7 7
  77. #define RXF8 8
  78. #define RXF9 9
  79. #define RXF10 10
  80. #define RXF11 11
  81. #define RXF12 12
  82. #define RXF13 13
  83. #define RXF14 14
  84. #define RXF15 15
  85. /*
  86. * Compile-time validation ECAN options as per ECAN and ECAN rules.
  87. */
  88. #if ( ECAN_SJW_VAL > 4 )
  89. #error Invalid SJW value received.
  90. #endif
  91. #if ( ECAN_BRP_VAL > 64 )
  92. #error Invalid BRP value received.
  93. #endif
  94. #if ( ECAN_PHSEG1_VAL > 8 )
  95. #error Invalid PHSEG1 value received.
  96. #endif
  97. #if ( ECAN_PHSEG2_VAL > 8 )
  98. #error Invalid PHSEG2 value received.
  99. #endif
  100. #if ( ECAN_PROPSEG_VAL > 8 )
  101. #error Invalid PROPSEG value received.
  102. #endif
  103. // In Mode 1 & 2, double buffering on RXB0 is not available.
  104. /*
  105. * In Mode 0, RXF0-RXF5 are always enabled.
  106. */
  107. #if ( ECAN_FUNC_MODE_VAL == ECAN_MODE_0 )
  108. #undef ECAN_RXF0_MODE_VAL
  109. #define ECAN_RXF0_MODE_VAL ECAN_RXF0_ENABLE
  110. #undef ECAN_RXF1_MODE_VAL
  111. #define ECAN_RXF1_MODE_VAL ECAN_RXF1_ENABLE
  112. #undef ECAN_RXF2_MODE_VAL
  113. #define ECAN_RXF2_MODE_VAL ECAN_RXF2_ENABLE
  114. #undef ECAN_RXF3_MODE_VAL
  115. #define ECAN_RXF3_MODE_VAL ECAN_RXF3_ENABLE
  116. #undef ECAN_RXF4_MODE_VAL
  117. #define ECAN_RXF4_MODE_VAL ECAN_RXF4_ENABLE
  118. #undef ECAN_RXF5_MODE_VAL
  119. #define ECAN_RXF5_MODE_VAL ECAN_RXF5_ENABLE
  120. #endif
  121. /*********************************************************************
  122. * Function: void ECANInitialize(void)
  123. *
  124. * Overview: Use this function to initialize ECAN module with
  125. * options defined in ECAN.def file.
  126. * You may manually edit ECAN.def file as per your
  127. * requirements, or use Microchip Application
  128. * Maestro tool.
  129. *
  130. * PreCondition: None
  131. *
  132. * Input: None
  133. *
  134. * Output: None
  135. *
  136. * Side Effects: All pending transmissions are aborted.
  137. ********************************************************************/
  138. void ECANInitialize(void)
  139. {
  140. // Put module into Configuration mode.
  141. ECANSetOperationMode(ECAN_OP_MODE_CONFIG);
  142. // Set Bit rate values as per defines.
  143. BRGCON1 = ((ECAN_SJW_VAL-1) << 6) | (ECAN_BRP_VAL-1);
  144. BRGCON2 = (ECAN_PHSEG2_MODE_VAL << 7) | \
  145. (ECAN_BUS_SAMPLE_MODE_VAL << 6) | \
  146. ((ECAN_PHSEG1_VAL-1) << 3) | \
  147. (ECAN_PROPSEG_VAL-1);
  148. BRGCON3 = (ECAN_WAKEUP_MODE_VAL << 7) |
  149. (ECAN_FILTER_MODE_VAL << 6) |
  150. (ECAN_PHSEG2_VAL-1);
  151. // Set CANTX2, TXDRIVE and CAN Capture modes.
  152. CIOCON = ECAN_TX2_SOURCE_VAL << 7 | \
  153. ECAN_TX2_MODE_VAL << 6 | \
  154. ECAN_TXDRIVE_MODE_VAL << 5 | \
  155. ECAN_CAPTURE_MODE_VAL;
  156. // Set WCAN functional mode.
  157. ECANCON_MDSEL1 = ECAN_FUNC_MODE_VAL >> 7;
  158. ECANCON_MDSEL0 = ECAN_FUNC_MODE_VAL >> 6;
  159. // Set RXB0 and RXB1 buffer modes.
  160. #if ( ECAN_FUNC_MODE_VAL == ECAN_MODE_0 )
  161. RXB0CON = (ECAN_RXB0_MODE_VAL << 5) | (ECAN_RXB0_DBL_BUFFER_MODE_VAL << 2);
  162. RXB1CON = ECAN_RXB1_MODE_VAL << 5;
  163. #else
  164. // In Mode1 & 2, Map 2-bit RXM bits into 1 RXM1 bit.
  165. #if ( ECAN_RXB0_MODE_VAL == ECAN_RECEIVE_ALL )
  166. RXB0CON = 0x40;
  167. #else
  168. RXB0CON = 0;
  169. #endif
  170. #if ( ECAN_RXB1_MODE_VAL == ECAN_RECEIVE_ALL )
  171. RXB1CON = 0x40;
  172. #else
  173. RXB1CON = 0;
  174. #endif
  175. #endif
  176. // B0-B5 are available in Mode 1 and 2 only.
  177. #if (ECAN_FUNC_MODE_VAL != ECAN_MODE_0)
  178. #if (ECAN_B0_TXRX_MODE_VAL != ECAN_BUFFER_TX)
  179. #if ( ECAN_B0_MODE_VAL == ECAN_RECEIVE_ALL )
  180. B0CON = 0x40;
  181. #else
  182. B0CON = 0;
  183. #endif
  184. #else
  185. B0CON = ECAN_B0_AUTORTR_MODE << 2;
  186. #endif
  187. #if (ECAN_B1_TXRX_MODE_VAL != ECAN_BUFFER_TX)
  188. #if ( ECAN_B1_MODE_VAL == ECAN_RECEIVE_ALL )
  189. B1CON = 0x40;
  190. #else
  191. B1CON = 0;
  192. #endif
  193. #else
  194. B1CON = ECAN_B1_AUTORTR_MODE << 2;
  195. #endif
  196. #if (ECAN_B2_TXRX_MODE_VAL != ECAN_BUFFER_TX)
  197. #if ( ECAN_B2_MODE_VAL == ECAN_RECEIVE_ALL )
  198. B2CON = 0x40;
  199. #else
  200. B2CON = 0;
  201. #endif
  202. #else
  203. B2CON = ECAN_B2_AUTORTR_MODE << 2;
  204. #endif
  205. #if (ECAN_B3_TXRX_MODE_VAL != ECAN_BUFFER_TX)
  206. #if ( ECAN_B3_MODE_VAL == ECAN_RECEIVE_ALL )
  207. B3CON = 0x40;
  208. #else
  209. B3CON = 0;
  210. #endif
  211. #else
  212. B3CON = ECAN_B3_AUTORTR_MODE << 2;
  213. #endif
  214. #if (ECAN_B4_TXRX_MODE_VAL != ECAN_BUFFER_TX)
  215. #if ( ECAN_B4_MODE_VAL == ECAN_RECEIVE_ALL )
  216. B4CON = 0x40;
  217. #else
  218. B4CON = 0;
  219. #endif
  220. #else
  221. B4CON = ECAN_B4_AUTORTR_MODE << 2;
  222. #endif
  223. #if (ECAN_B5_TXRX_MODE_VAL != ECAN_BUFFER_TX)
  224. #if ( ECAN_B5_MODE_VAL == ECAN_RECEIVE_ALL )
  225. B5CON = 0x40;
  226. #else
  227. B5CON = 0;
  228. #endif
  229. #else
  230. B5CON = ECAN_B5_AUTORTR_MODE << 2;
  231. #endif
  232. // Enable/disable buffers B0-B5.
  233. BSEL0 = ECAN_B5_TXRX_MODE_VAL << 7 | \
  234. ECAN_B4_TXRX_MODE_VAL << 6 | \
  235. ECAN_B3_TXRX_MODE_VAL << 5 | \
  236. ECAN_B2_TXRX_MODE_VAL << 4 | \
  237. ECAN_B1_TXRX_MODE_VAL << 3 | \
  238. ECAN_B0_TXRX_MODE_VAL << 2;
  239. #endif
  240. // Assign value to RXF0 only if Mode0 is used or RXF0 itself is enabled.
  241. #if ( (ECAN_RXF0_MODE_VAL == ECAN_RXFn_ENABLE) || (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  242. // Set Standard or Extended value.
  243. #if ( ECAN_RXF0_MSG_TYPE_VAL == ECAN_MSG_STD )
  244. //_SetStdRXFnValue(RXF0, ECAN_RXF0_VAL);
  245. RXF0SIDH = (long)ECAN_RXF0_VAL >> 3L;
  246. RXF0SIDL = (long)ECAN_RXF0_VAL >> 5L;
  247. #else
  248. _SetXtdRXFnValue(RXF0, ECAN_RXF0_VAL);
  249. #endif
  250. #endif
  251. #if ( (ECAN_RXF1_MODE_VAL == ECAN_RXFn_ENABLE) || (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  252. #if ( ECAN_RXF1_MSG_TYPE_VAL == ECAN_MSG_STD )
  253. //_SetStdRXFnValue(RXF1, ECAN_RXF1_VAL);
  254. RXF1SIDH = (long)ECAN_RXF1_VAL >> 3L;
  255. RXF1SIDL = (long)ECAN_RXF1_VAL >> 5L;
  256. #else
  257. _SetXtdRXFnValue(RXF1, ECAN_RXF1_VAL);
  258. #endif
  259. #endif
  260. #if ( (ECAN_RXF2_MODE_VAL == ECAN_RXFn_ENABLE) || (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  261. #if ( ECAN_RXF2_MSG_TYPE_VAL == ECAN_MSG_STD )
  262. //_SetStdRXFnValue(RXF2, ECAN_RXF2_VAL);
  263. RXF2SIDH = (long)ECAN_RXF2_VAL >> 3L;
  264. RXF2SIDL = (long)ECAN_RXF2_VAL >> 5L;
  265. #else
  266. _SetXtdRXFnValue(RXF3, ECAN_RXF3_VAL);
  267. #endif
  268. #endif
  269. #if ( (ECAN_RXF3_MODE_VAL == ECAN_RXFn_ENABLE) || (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  270. #if ( ECAN_RXF3_MSG_TYPE_VAL == ECAN_MSG_STD )
  271. _SetStdRXFnValue(RXF3, ECAN_RXF3_VAL);
  272. #else
  273. _SetXtdRXFnValue(RXF3, ECAN_RXF3_VAL);
  274. #endif
  275. #endif
  276. #if ( (ECAN_RXF4_MODE_VAL == ECAN_RXFn_ENABLE) || (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  277. #if ( ECAN_RXF4_MSG_TYPE_VAL == ECAN_MSG_STD )
  278. _SetStdRXFnValue(RXF4, ECAN_RXF4_VAL);
  279. #else
  280. _SetXtdRXFnValue(RXF4, ECAN_RXF4_VAL);
  281. #endif
  282. #endif
  283. #if ( (ECAN_RXF5_MODE_VAL == ECAN_RXFn_ENABLE) || (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  284. #if ( ECAN_RXF5_MSG_TYPE_VAL == ECAN_MSG_STD )
  285. _SetStdRXFnValue(RXF5, ECAN_RXF4_VAL);
  286. #else
  287. _SetXtdRXFnValue(RXF5, ECAN_RXF5_VAL);
  288. #endif
  289. #endif
  290. // Filters 6-15 are available in Modes 1 and 2 only.
  291. #if (ECAN_FUNC_MODE_VAL != ECAN_MODE_0)
  292. #if ( ECAN_RXF6_MODE_VAL == ECAN_RXFn_ENABLE )
  293. #if ( ECAN_RXF6_MSG_TYPE_VAL == ECAN_MSG_STD )
  294. _SetStdRXFnValue(RXF6, ECAN_RXF6_VAL);
  295. #else
  296. _SetXtdRXFnValue(RXF6, ECAN_RXF6_VAL);
  297. #endif
  298. #endif
  299. #if ( ECAN_RXF7_MODE_VAL == ECAN_RXFn_ENABLE )
  300. #if ( ECAN_RXF7_MSG_TYPE_VAL == ECAN_MSG_STD )
  301. _SetStdRXFnValue(RXF7, ECAN_RXF7_VAL);
  302. #else
  303. _SetXtdRXFnValue(RXF7, ECAN_RXF7_VAL);
  304. #endif
  305. #endif
  306. #if ( ECAN_RXF8_MODE_VAL == ECAN_RXFn_ENABLE )
  307. #if ( ECAN_RXF8_MSG_TYPE_VAL == ECAN_MSG_STD )
  308. _SetStdRXFnValue(RXF8, ECAN_RXF9_VAL);
  309. #else
  310. _SetXtdRXFnValue(RXF8, ECAN_RXF9_VAL);
  311. #endif
  312. #endif
  313. #if ( ECAN_RXF9_MODE_VAL == ECAN_RXFn_ENABLE )
  314. #if ( ECAN_RXF9_MSG_TYPE_VAL == ECAN_MSG_STD )
  315. _SetStdRXFnValue(RXF9, ECAN_RXF9_VAL);
  316. #else
  317. _SetXtdRXFnValue(RXF9, ECAN_RXF9_VAL);
  318. #endif
  319. #endif
  320. #if ( ECAN_RXF10_MODE_VAL == ECAN_RXFn_ENABLE )
  321. #if ( ECAN_RXF10_MSG_TYPE_VAL == ECAN_MSG_STD )
  322. _SetStdRXFnValue(RXF10, ECAN_RXF10_VAL);
  323. #else
  324. _SetXtdRXFnValue(RXF10, ECAN_RXF10_VAL);
  325. #endif
  326. #endif
  327. #if ( ECAN_RXF11_MODE_VAL == ECAN_RXFn_ENABLE )
  328. #if ( ECAN_RXF11_MSG_TYPE_VAL == ECAN_MSG_STD )
  329. _SetStdRXFnValue(RXF11, ECAN_RXF11_VAL);
  330. #else
  331. _SetXtdRXFnValue(RXF11, ECAN_RXF11_VAL);
  332. #endif
  333. #endif
  334. #if ( ECAN_RXF12_MODE_VAL == ECAN_RXFn_ENABLE )
  335. #if ( ECAN_RXF12_MSG_TYPE_VAL == ECAN_MSG_STD )
  336. _SetStdRXFnValue(RXF12, ECAN_RXF12_VAL);
  337. #else
  338. _SetXtdRXFnValue(RXF12, ECAN_RXF12_VAL);
  339. #endif
  340. #endif
  341. #if ( ECAN_RXF13_MODE_VAL == ECAN_RXFn_ENABLE )
  342. #if ( ECAN_RXF13_MSG_TYPE_VAL == ECAN_MSG_STD )
  343. _SetStdRXFnValue(RXF13, ECAN_RXF13_VAL);
  344. #else
  345. _SetXtdRXFnValue(RXF13, ECAN_RXF13_VAL);
  346. #endif
  347. #endif
  348. #if ( ECAN_RXF14_MODE_VAL == ECAN_RXFn_ENABLE )
  349. #if ( ECAN_RXF14_MSG_TYPE_VAL == ECAN_MSG_STD )
  350. _SetStdRXFnValue(RXF14, ECAN_RXF14_VAL);
  351. #else
  352. _SetXtdRXFnValue(RXF14, ECAN_RXF14_VAL);
  353. #endif
  354. #endif
  355. #if ( ECAN_RXF15_MODE_VAL == ECAN_RXFn_ENABLE )
  356. #if ( ECAN_RXF15_MSG_TYPE_VAL == ECAN_MSG_STD )
  357. _SetStdRXFnValue(RXF15, ECAN_RXF15_VAL);
  358. #else
  359. _SetXtdRXFnValue(RXF15, ECAN_RXF15_VAL);
  360. #endif
  361. #endif
  362. #endif
  363. // Enable/Disable filters in Modes 1 and 2 only.
  364. #if ( ECAN_FUNC_MODE_VAL != ECAN_MODE_0 )
  365. RXFCON0 = (ECAN_RXF7_MODE_VAL << 7) | \
  366. (ECAN_RXF6_MODE_VAL << 6) | \
  367. (ECAN_RXF5_MODE_VAL << 5) | \
  368. (ECAN_RXF4_MODE_VAL << 4) | \
  369. (ECAN_RXF3_MODE_VAL << 3) | \
  370. (ECAN_RXF2_MODE_VAL << 2) | \
  371. (ECAN_RXF1_MODE_VAL << 1) | \
  372. (ECAN_RXF0_MODE_VAL);
  373. RXFCON1 = (ECAN_RXF15_MODE_VAL << 7) | \
  374. (ECAN_RXF14_MODE_VAL << 6) | \
  375. (ECAN_RXF13_MODE_VAL << 5) | \
  376. (ECAN_RXF12_MODE_VAL << 4) | \
  377. (ECAN_RXF11_MODE_VAL << 3) | \
  378. (ECAN_RXF10_MODE_VAL << 2) | \
  379. (ECAN_RXF9_MODE_VAL << 1) | \
  380. (ECAN_RXF8_MODE_VAL);
  381. #endif
  382. // Link each filter to corresponding buffer only if we are in Mode 1 or 2.
  383. #if ( ECAN_FUNC_MODE_VAL != ECAN_MODE_0 )
  384. ECANLinkRXF0F1ToBuffer(ECAN_RXF0_BUFFER_VAL, ECAN_RXF1_BUFFER_VAL);
  385. ECANLinkRXF2F3ToBuffer(ECAN_RXF2_BUFFER_VAL, ECAN_RXF3_BUFFER_VAL);
  386. ECANLinkRXF4F5ToBuffer(ECAN_RXF4_BUFFER_VAL, ECAN_RXF5_BUFFER_VAL);
  387. ECANLinkRXF6F7ToBuffer(ECAN_RXF6_BUFFER_VAL, ECAN_RXF7_BUFFER_VAL);
  388. ECANLinkRXF8F9ToBuffer(ECAN_RXF8_BUFFER_VAL, ECAN_RXF9_BUFFER_VAL);
  389. ECANLinkRXF10F11ToBuffer(ECAN_RXF10_BUFFER_VAL, ECAN_RXF11_BUFFER_VAL);
  390. ECANLinkRXF12F13ToBuffer(ECAN_RXF12_BUFFER_VAL, ECAN_RXF13_BUFFER_VAL);
  391. ECANLinkRXF14F15ToBuffer(ECAN_RXF14_BUFFER_VAL, ECAN_RXF15_BUFFER_VAL);
  392. ECANLinkRXF0Thru3ToMask(ECAN_RXF0_MASK_VAL, \
  393. ECAN_RXF1_MASK_VAL, \
  394. ECAN_RXF2_MASK_VAL, \
  395. ECAN_RXF3_MASK_VAL);
  396. ECANLinkRXF4Thru7ToMask(ECAN_RXF4_MASK_VAL, \
  397. ECAN_RXF5_MASK_VAL, \
  398. ECAN_RXF6_MASK_VAL, \
  399. ECAN_RXF7_MASK_VAL);
  400. ECANLinkRXF8Thru11ToMask(ECAN_RXF8_MASK_VAL, \
  401. ECAN_RXF9_MASK_VAL, \
  402. ECAN_RXF10_MASK_VAL, \
  403. ECAN_RXF11_MASK_VAL);
  404. ECANLinkRXF12Thru15ToMask(ECAN_RXF12_MASK_VAL, \
  405. ECAN_RXF13_MASK_VAL, \
  406. ECAN_RXF14_MASK_VAL, \
  407. ECAN_RXF15_MASK_VAL);
  408. #endif
  409. #if ( ECAN_RXM0_MSG_TYPE == ECAN_MSG_STD )
  410. _SetStdRXMnValue(0, ECAN_RXM0_VAL);
  411. RXM0SIDL_EXIDEN = 0;
  412. #else
  413. _SetXtdRXMnValue(0, ECAN_RXM0_VAL);
  414. RXM0SIDL_EXIDEN = 1;
  415. #endif
  416. #if ECAN_RXM1_MSG_TYPE == ECAN_MSG_STD
  417. _SetStdRXMnValue(1, ECAN_RXM1_VAL);
  418. RXM1SIDL_EXIDEN = 0;
  419. #else
  420. _SetXtdRXMnValue(1, ECAN_RXM1_VAL);
  421. RXM1SIDL_EXIDEN = 1;
  422. #endif
  423. // SDFLC value
  424. // Exit with speicfied mode. If selected mode is Configuration,
  425. // we do not need to do anything.
  426. #if ( ECAN_INIT_MODE != ECAN_INIT_CONFIGURATION )
  427. ECANSetOperationMode(ECAN_INIT_MODE);
  428. #endif
  429. }
  430. /*********************************************************************
  431. * Function: BOOL ECANLoadRTRBuffer(BYTE buffer,
  432. * unsigned long id,
  433. * BYTE *data,
  434. * BYTE dataLen,
  435. * BYTE type)
  436. *
  437. * Overview: Use this function to update automatic RTR buffer.
  438. *
  439. *
  440. * PreCondition: None
  441. *
  442. * Input: buffer - Buffer number that is to be loaded
  443. * id - CAN message identifier.
  444. * Only 11 or 29 bits may be used
  445. * depending on standard or extended
  446. * message type as specified in
  447. * type parameter.
  448. * data - Data bytes of upto 8 bytes in length
  449. * dataLen - Data length from 0 thru 8.
  450. * If 0, data may be NULL.
  451. * type - Buffer type
  452. * Must be ECAN_MSG_STD for Standard
  453. * ECAN_MSG_XTD for Extended
  454. *
  455. * Output: TRUE, if given data was successfully loaded
  456. * FALSE, if RTR buffer was in process of transmitting
  457. * automated response.
  458. *
  459. * Side Effects: None
  460. *
  461. ********************************************************************/
  462. #if ( defined(ECAN_ENABLE_AUTO_RTR) )
  463. BOOL ECANLoadRTRBuffer(BYTE buffer,
  464. unsigned long id,
  465. BYTE *data,
  466. BYTE dataLen,
  467. BYTE type)
  468. {
  469. BYTE *pBuffer;
  470. BYTE *pSavedBuffer;
  471. BYTE i;
  472. pSavedBuffer = pBuffer;
  473. #if defined(ECAN_CHECKED_BUILD)
  474. // Make sure that this buffer is configured for RTR handling.
  475. if ( !((BYTE_VAL*)pBuffer)->bits.b2 )
  476. return FALSE;
  477. #endif
  478. /*
  479. * Make sure that RTR response is not currently being transmitted.
  480. */
  481. if ( ((BYTE_VAL*)pBuffer)->bits.b4 )
  482. return FALSE;
  483. // Start with zero length.
  484. *(pBuffer+5) = 0;
  485. // Save given id into ID registers..
  486. _CANIDToRegs((BYTE*)(pBuffer+1), id, type);
  487. // Prepare for data byte access.
  488. pBuffer += 6;
  489. // Copy given number of data bytes.
  490. for ( i = 0; i < dataLen; i++ )
  491. *pBuffer++ = *data++;
  492. // At last, update DLC value.
  493. *(pSavedBuffer + 5) = dataLen;
  494. return TRUE;
  495. }
  496. #endif
  497. /*********************************************************************
  498. * Function: BOOL ECANSendMessage(unsigned long id,
  499. * BYTE *data,
  500. * BYTE dataLen,
  501. * ECAN_TX_MSG_FLAGS msgFlags)
  502. *
  503. * Overview: Use this function to transmit a CAN message.
  504. * This function searches for empty transmit buffer
  505. * and loads it with given messages. Buffer is then
  506. * marked for ready to transmit.
  507. *
  508. * PreCondition: None
  509. *
  510. * Input: id - CAN message identifier.
  511. * Only 11 or 29 bits may be used
  512. * depending on standard or extended
  513. * message type as specified in
  514. * msgFlags parameter.
  515. * data - Data bytes of upto 8 bytes in length
  516. * dataLen - Data length from 0 thru 8.
  517. * If 0, data may be NULL.
  518. * msgFlags - One or ECAN_TX_MSG_FLAGS values ORed
  519. * together
  520. *
  521. * Output: TRUE, if an empty buffer was found and loaded with
  522. * given data
  523. * FALSE, if otherwise.
  524. *
  525. * Side Effects: None
  526. *
  527. ********************************************************************/
  528. BOOL ECANSendMessage( unsigned long id,
  529. BYTE* data,
  530. BYTE dataLen,
  531. ECAN_TX_MSG_FLAGS msgFlags)
  532. {
  533. #if ( ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME )
  534. BYTE mode;
  535. BYTE buffers;
  536. #elif ( ECAN_FUNC_MODE == ECAN_MODE_0 )
  537. #define buffers 2
  538. #else
  539. #define buffers 8
  540. #endif
  541. BYTE i,j;
  542. BYTE *ptr, *tempPtr;
  543. BYTE* pb[9];
  544. BYTE temp;
  545. //#if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || (ECAN_FUNC_MODE != ECAN_MODE_0) )
  546. BYTE_VAL tempBSEL0;
  547. //#endif
  548. /*
  549. * Since there are more than one transmit buffers and they are scattered in
  550. * SFR map, prepare table of all transmit buffers.
  551. */
  552. pb[0]=(BYTE*)&TXB0CON;
  553. pb[1]=(BYTE*)&TXB1CON;
  554. pb[2]=(BYTE*)&TXB2CON;
  555. /*
  556. * Include programmable buffers only if mode 1 or 2 is used.
  557. */
  558. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || (ECAN_FUNC_MODE != ECAN_MODE_0) )
  559. pb[3]=(BYTE*)&B0CON;
  560. pb[4]=(BYTE*)&B1CON;
  561. pb[5]=(BYTE*)&B2CON;
  562. pb[6]=(BYTE*)&B3CON;
  563. pb[7]=(BYTE*)&B4CON;
  564. pb[8]=(BYTE*)&B5CON;
  565. #endif
  566. #if ( ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME )
  567. mode = ECANCON&0xC0;
  568. if ( mode == ECAN_MODE_0 )
  569. buffers = 2;
  570. else
  571. buffers = 8;
  572. #endif
  573. /*
  574. * Depending on whether only mode 0 is used or not, we would only need to check
  575. * either 3 or all buffers.
  576. */
  577. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_FIXED) && (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  578. for ( i = 0; i < buffers; i++ )
  579. #else
  580. /*
  581. * In Mode 1 & 2, programmable buffers must be checked for buffer mode.
  582. * By remembering BSEL0 (programmable buffer mode type info), we can
  583. * reduce code required to check invidual buffer type as we scan through
  584. * all buffers.
  585. */
  586. tempBSEL0.Val = BSEL0 >> 1;
  587. for ( i = 0; i < buffers; i++ )
  588. #endif
  589. {
  590. /*
  591. * Use local poiter to reduce overall code.
  592. * It will be more efficient to access using pointer instead of index.
  593. */
  594. ptr = pb[i];
  595. tempPtr = ptr;
  596. /*
  597. * In Mode 1 & 2, if buffer number is above TXB2, we must also check to
  598. * see if this buffer is configured for transmit mode.
  599. */
  600. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || (ECAN_FUNC_MODE_VAL != ECAN_MODE_0) )
  601. if ( i > 2 )
  602. {
  603. /*
  604. * Use previously saved BSEL0 value.
  605. */
  606. tempBSEL0.Val >>= 1;
  607. /*
  608. * If this is not transmit buffer, continue with next buffer.
  609. */
  610. if ( !tempBSEL0.bits.b0 )
  611. continue;
  612. }
  613. #endif
  614. /*
  615. * Check to see if this buffer is empty by looking at BnCON.TXREQ bit (bit3).
  616. */
  617. if ( !(*ptr & 0x08) )
  618. {
  619. // Set transmit priority in BnCON register.
  620. *ptr &= ~ECAN_TX_PRIORITY_BITS;
  621. *ptr |= msgFlags & ECAN_TX_PRIORITY_BITS;
  622. // Also save DLC value.
  623. if ( msgFlags & ECAN_TX_RTR_BIT )
  624. temp = 0x40 | dataLen;
  625. else
  626. temp = dataLen;
  627. // Use temp to reduce evaluation of *(ptr+5) to only once.
  628. *(ptr+5) = temp;
  629. // Set standard or extended message type.
  630. if ( msgFlags & ECAN_TX_FRAME_BIT )
  631. temp = ECAN_MSG_XTD;
  632. else
  633. temp = ECAN_MSG_STD;
  634. // And rearrange given id accordingly.
  635. _CANIDToRegs((BYTE*)(ptr+1), id, temp);
  636. // Prepare for data byte access.
  637. ptr += 6;
  638. // Copy given number of data bytes.
  639. for ( j = 0 ; j < dataLen; j++ )
  640. *ptr++ = *data++;
  641. // If this buffer is configured to automatically handle RTR messages,
  642. // do not set TXREQ bit. TXREQ bit will be set whenever matching RTR is received.
  643. if ( !(*tempPtr & 0x04) )
  644. *tempPtr |= 0x08;
  645. return TRUE;
  646. }
  647. }
  648. // There were no empty buffers.
  649. return FALSE;
  650. }
  651. /*********************************************************************
  652. * Function: BOOL ECANReceiveMessage(unsigned long *id,
  653. * BYTE *data,
  654. * BYTE *dataLen,
  655. * ECAN_RX_MSG_FLAGS *msgFlags)
  656. *
  657. * Overview: Use this function to check for full receive buffer
  658. * and extract received data into local buffers.
  659. *
  660. * PreCondition: None
  661. *
  662. * Input: id - Pointer to buffer that will be
  663. * populated with receive ID.
  664. * data - Pointer to buffer that will be
  665. * populated with data if there is any
  666. * dataLen - Pointer to buffer that will be
  667. * populated with count of bytes
  668. * copied in data buffer.
  669. * msgFlags - Pointer to buffer that will be
  670. * copied with information about
  671. * received message. More than
  672. * one information is ORed together.
  673. *
  674. * Output: TRUE, if a full receive buffer was found and
  675. * given parameters were populated.
  676. * FALSE, if otherwise.
  677. *
  678. * Side Effects: None
  679. *
  680. * Note: If you need to know the filter number that caused
  681. * this message to get accepted, call
  682. * ECANGetFilterHitInfo().
  683. *
  684. ********************************************************************/
  685. BOOL ECANReceiveMessage(unsigned long *id,
  686. BYTE *data,
  687. BYTE *dataLen,
  688. ECAN_RX_MSG_FLAGS *msgFlags)
  689. {
  690. #if ( ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME )
  691. BYTE mode;
  692. #endif
  693. BYTE *ptr, *savedPtr;
  694. char i;
  695. BYTE_VAL temp;
  696. _ECANRxFilterHitInfo.Val = 0;
  697. #if ( ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME )
  698. mode = ECANCON&0xC0;
  699. if ( mode == ECAN_MODE_0 )
  700. #endif
  701. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || \
  702. (ECAN_LIB_MODE_VAL == ECAN_LIB_FIXED) && (ECAN_FUNC_MODE_VAL == ECAN_MODE_0) )
  703. {
  704. // Find which buffer is ready.
  705. if ( RXB0CON_RXFUL )
  706. {
  707. // Clear the received flag.
  708. PIR3_RXB0IF = 0;
  709. // Record and forget any previous overflow
  710. if ( COMSTAT_RXB0OVFL )
  711. {
  712. *msgFlags |= ECAN_RX_OVERFLOW;
  713. COMSTAT_RXB0OVFL = 0;
  714. }
  715. _ECANRxFilterHitInfo.bits.b0 = RXB0CON_FILHIT0;
  716. ptr = (BYTE*)&RXB0CON;
  717. }
  718. else if ( RXB1CON_RXFUL )
  719. {
  720. // Clear the received flag.
  721. PIR3_RXB1IF = 0;
  722. // Record and forget any previous overflow
  723. if ( COMSTAT_RXB1OVFL )
  724. {
  725. *msgFlags |= ECAN_RX_OVERFLOW;
  726. COMSTAT_RXB1OVFL = 0;
  727. }
  728. _ECANRxFilterHitInfo.Val = RXB1CON & 0x07;
  729. if ( _ECANRxFilterHitInfo.Val < 0x02 )
  730. *msgFlags |= ECAN_RX_DBL_BUFFERED;
  731. ptr = (BYTE*)&RXB1CON;
  732. }
  733. else
  734. return FALSE;
  735. goto _SaveMessage;
  736. }
  737. #endif
  738. #if ( ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME )
  739. else if ( mode == ECAN_MODE_1 )
  740. #endif
  741. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || \
  742. (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_FIXED) && (ECAN_FUNC_MODE_VAL == ECAN_MODE_1) )
  743. {
  744. if ( RXB0CON_RXFUL )
  745. ptr = (BYTE*)&RXB0CON;
  746. else if (RXB1CON_RXFUL)
  747. ptr = (BYTE*)&RXB1CON;
  748. else if ( (BSEL0_B0TXEN==0) && B0CON_RXFUL )
  749. ptr = (BYTE*)&B0CON;
  750. else if ( (BSEL0_B1TXEN==0) && B1CON_RXFUL )
  751. ptr = (BYTE*)&B1CON;
  752. else if ( (BSEL0_B2TXEN==0) && B2CON_RXFUL )
  753. ptr = (BYTE*)&B2CON;
  754. else if ( (BSEL0_B3TXEN==0) && B3CON_RXFUL )
  755. ptr = (BYTE*)&B3CON;
  756. else if ( (BSEL0_B4TXEN==0) && B4CON_RXFUL )
  757. ptr = (BYTE*)&B4CON;
  758. else if ( (BSEL0_B5TXEN==0) && B5CON_RXFUL )
  759. ptr = (BYTE*)&B5CON;
  760. else
  761. return FALSE;
  762. goto _SaveMode12Message;
  763. }
  764. #endif
  765. #if ( ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME )
  766. else
  767. #endif
  768. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || \
  769. (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_FIXED) && (ECAN_FUNC_MODE_VAL == ECAN_MODE_2) )
  770. {
  771. if ( COMSTAT_FIFOEMPTY == 1 ) //if FIFO is NOT empty --> meaning there is a message to be read waiting in Bn or RXBn Buffer
  772. {
  773. ptr = (BYTE*)_ECANPointBuffer(CANCON&0x07); // get the pointer to the proper buffer
  774. goto _SaveMode12Message;
  775. }
  776. return FALSE;
  777. }
  778. #endif
  779. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || (ECAN_FUNC_MODE_VAL != ECAN_MODE_0) )
  780. _SaveMode12Message:
  781. _ECANRxFilterHitInfo.Val = *ptr & 0x1f;
  782. PIR5bits.RXB1IF = 0;
  783. if ( COMSTAT_RXBnOVFL )
  784. {
  785. *msgFlags |= ECAN_RX_OVERFLOW;
  786. COMSTAT_RXBnOVFL = 0;
  787. }
  788. #endif
  789. _SaveMessage:
  790. savedPtr = ptr;
  791. *msgFlags = 0;
  792. // Retrieve message length.
  793. temp.Val = *(ptr+5);
  794. *dataLen = temp.Val & 0b00001111;
  795. // Determine whether this was RTR or not.
  796. if ( temp.bits.b6 )
  797. *msgFlags |= ECAN_RX_RTR_FRAME;
  798. // Retrieve EIDX bytes only if this is extended message
  799. temp.Val = *(ptr+2);
  800. if ( temp.bits.b3 )
  801. {
  802. *msgFlags |= ECAN_RX_XTD_FRAME;
  803. temp.Val = ECAN_MSG_XTD;
  804. }
  805. else
  806. temp.Val = ECAN_MSG_STD;
  807. _RegsToCANID(ptr+1, id, temp.Val);
  808. // Get message data itself
  809. ptr += 6;
  810. temp.Val = *dataLen;
  811. for ( i = 0; i < temp.Val; i++ )
  812. *data++ = *ptr++;
  813. // Record and Clear any previous invalid message bit flag.
  814. if ( PIR5bits.IRXIF )
  815. {
  816. *msgFlags |= ECAN_RX_INVALID_MSG;
  817. PIR5bits.IRXIF = 0;
  818. }
  819. // Mark that this buffer is read and empty.
  820. *savedPtr &= 0x7f;
  821. #if ( ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME )
  822. // Workaround for Rev A1 silicon
  823. if ( mode == ECAN_MODE_2 )
  824. COMSTAT_FIFOEMPTY = 0;
  825. #elif ( ECAN_FUNC_MODE_VAL == ECAN_MODE_2 )
  826. COMSTAT_FIFOEMPTY = 0;
  827. #endif
  828. return TRUE;
  829. }
  830. /*********************************************************************
  831. * Function: void ECANSetOperationMode(ECAN_OP_MODE mode)
  832. *
  833. * Overview: Use this function to switch ECAN module into
  834. * given operational mode.
  835. *
  836. * PreCondition: None
  837. *
  838. * Input: mode - Operation mode code
  839. * must be of type ECAN_OP_MODES
  840. *
  841. * Output: MCU is set to requested mode
  842. *
  843. * Side Effects: None
  844. *
  845. * Note: This is a blocking call. It will not return until
  846. * requested mode is set.
  847. ********************************************************************/
  848. void ECANSetOperationMode(ECAN_OP_MODE mode)
  849. {
  850. CANCON &= 0x1F; // clear previous mode
  851. CANCON |= mode; // set new mode
  852. while( ECANGetOperationMode() != mode ); // Wait till desired mode is set.
  853. }
  854. /*********************************************************************
  855. * Function: void _CANIDToRegs(BYTE* ptr,
  856. * unsigned long val,
  857. * ECAN_MSG_TYPE type)
  858. *
  859. * PreCondition: None
  860. *
  861. * Input: ptr - Starting address of a buffer to be updated
  862. * val - 32-bit value to be converted
  863. * type - Type of message - either
  864. * CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG
  865. *
  866. * Output: Given CAN id value 'val' is bit adjusted and copied
  867. * into corresponding PIC18CXX8 CAN registers
  868. *
  869. * Side Effects: None
  870. *
  871. * Overview: If given id is of type standard identifier,
  872. * only SIDH and SIDL are updated
  873. * If given id is of type extended identifier,
  874. * bits val<17:0> is copied to EIDH, EIDL and SIDH<1:0>
  875. * bits val<28:18> is copied to SIDH and SIDL
  876. *
  877. ********************************************************************/
  878. //////////////////////////////////////////////////////////////////////
  879. /*********************************************************************
  880. *
  881. * union CAN_MESSAGE_ID
  882. *
  883. * This union provides abstract data type for CAN message id.
  884. * It is used for both 11-bit and 29-bit message identifiers.
  885. * There are multiple union members to be able to access individual
  886. * parts of it.
  887. *
  888. ********************************************************************/
  889. // Parse-out 29-bit or 11-bit (saved in 32-bit number)
  890. typedef union _CAN_MESSAGE_ID
  891. {
  892. unsigned long ID;
  893. struct
  894. {
  895. struct
  896. {
  897. unsigned SIDL:3; // SIDL<5:7>
  898. unsigned SIDH:5; // SIDH<0:4>
  899. } BYTE1;
  900. struct
  901. {
  902. unsigned SIDHU:3; // SIDH<5:7>
  903. unsigned EIDL_LN:5; // EIDL<0:4>
  904. } BYTE2;
  905. struct
  906. {
  907. unsigned EIDL_UN:3; // EIDL<5:7>
  908. unsigned EIDH_LN:5; // EIDH<0:4>
  909. } BYTE3;
  910. struct
  911. {
  912. unsigned EIDH_UN:3; // EIDH<5:7>
  913. unsigned EIDHU:2; // SIDL<0:1>
  914. unsigned :3;
  915. } BYTE4;
  916. } ID_VALS;
  917. // This is to allow individual byte access within message id.
  918. struct
  919. {
  920. BYTE BYTE_1;
  921. BYTE BYTE_2;
  922. BYTE BYTE_3;
  923. BYTE BYTE_4;
  924. } BYTES;
  925. } CAN_MESSAGE_ID;
  926. void _CANIDToRegs(BYTE* ptr,
  927. unsigned long val,
  928. BYTE type)
  929. {
  930. CAN_MESSAGE_ID *Value;
  931. Value = (CAN_MESSAGE_ID*)&val;
  932. if ( type == ECAN_MSG_STD )
  933. {
  934. // Standard Identifier
  935. *ptr = Value->BYTES.BYTE_1 >> 3; // Copy SID<7:3> to SIDH<4:0>
  936. *ptr |= (Value->BYTES.BYTE_2 << 5); // Copy SID<10:8> to SIDH<7:5>
  937. ptr++; // Point to SIDL
  938. *ptr = Value->BYTES.BYTE_1 << 5; // Copy SID<2:0> to SIDL<7:5>
  939. }
  940. else
  941. {
  942. // Extended Identifier
  943. *ptr = Value->BYTES.BYTE_3 >> 5; // Copy EID<23:21> to SIDH<2:0>
  944. *ptr |= Value->BYTES.BYTE_4 << 3; // Copy EID<28:24> to SIDH<7:3>
  945. ptr++; // Point to SIDL
  946. *ptr = (Value->BYTES.BYTE_3 << 3) & 0xE0; // Copy EID<20:18> to SIDL<7:5>
  947. // mask out EID<17:16> bits
  948. *ptr |= 0b00001000; // Set EXIDEN bit to SIDL<3>
  949. *ptr |= Value->BYTES.BYTE_3 & 0x03; // Copy EID<17:16> to SIDL<1:0>
  950. ptr++; // Point to EIDH
  951. *ptr = Value->BYTES.BYTE_2; // Copy EID<15:8> to EIDH<7:0>
  952. ptr++; // Point to EIDL
  953. *ptr = Value->BYTES.BYTE_1; // Copy EID<7:0> to EIDL<7:0>
  954. }
  955. }
  956. /*********************************************************************
  957. * Function: void _RegsToCANID(BYTE *ptr,
  958. * unsigned long *val,
  959. * BYTE type)
  960. *
  961. * PreCondition: None
  962. *
  963. * Input: ptr - Starting address of a buffer to be updated
  964. * val - 32-bit buffer to hold value
  965. * type - Type of message - either
  966. * CAN_CONFIG_XTD_MSG or CAN_CONFIG_STD_MSG
  967. *
  968. * Output: CAN registers starting at given address are bit
  969. * adjusted and copied into 'val'
  970. *
  971. * Side Effects: None
  972. *
  973. * Overview: If given id is of type standard identifier,
  974. * only SIDH and SIDL are used
  975. * If given id is of type extended identifier,
  976. * bits EIDH, EIDL and SIDL<1:0> is copied to val<17:0>
  977. * bits SIDH and SIDL is copied to val<28:18>
  978. *
  979. ********************************************************************/
  980. void _RegsToCANID( BYTE* ptr,
  981. unsigned long *val,
  982. BYTE type )
  983. {
  984. CAN_MESSAGE_ID *Value;
  985. Value = (CAN_MESSAGE_ID*)val;
  986. if ( type == ECAN_MSG_STD )
  987. {
  988. // Standard Identifier
  989. Value->BYTES.BYTE_1 = (*ptr << 3); // Copy SIDH<4:0> to SID<7:3>
  990. Value->BYTES.BYTE_2 = *ptr >> 5; // Copy SIDH<7:5> to SID<10:8>
  991. ptr++; // Point to SIDL
  992. Value->BYTES.BYTE_1 |= (*ptr >> 5); // Copy SIDL<7:6> to SID<2:0>
  993. Value->BYTES.BYTE_3 = 0x00;
  994. Value->BYTES.BYTE_4 = 0x00;
  995. }
  996. else
  997. {
  998. // Extended Identifier
  999. Value->BYTES.BYTE_3 = (*ptr << 5); // Copy SIDH<2:0> to EID<23:21>
  1000. Value->BYTES.BYTE_4 = (*ptr >> 3); // Copy SIDH<7:3> to EID<29:25>
  1001. ptr++; // Point to SIDL
  1002. Value->BYTES.BYTE_3 |= (*ptr & 0x03); // Copy SIDH<1:0> to EID<17:16>
  1003. // Bug-Fix NKR 11/20/00
  1004. Value->BYTES.BYTE_3 |= ((*ptr & 0xe0) >> 3); // Copy SIDL<7:6> to EID<20:18>
  1005. ptr++; // Point to EIDH
  1006. Value->BYTES.BYTE_2 = *ptr; // Copy EIDH<15:8> to EID<15:8>
  1007. ptr++; // Point to EIDL
  1008. Value->BYTES.BYTE_1 = *ptr; // Copy EIDH<7:0> to EID<7:0>
  1009. }
  1010. }
  1011. /*********************************************************************
  1012. * Function: BYTE* _ECANPointBuffer(BYTE b)
  1013. *
  1014. * PreCondition: None
  1015. *
  1016. * Input: buffer number
  1017. *
  1018. * Output: RXBnCON or RnCON address
  1019. *
  1020. * Side Effects: None
  1021. *
  1022. * Overview: This functions returns a pointer to the
  1023. * beginning of a reception buffer
  1024. *
  1025. * Note:
  1026. ********************************************************************/
  1027. #if ( (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_RUN_TIME) || \
  1028. (ECAN_LIB_MODE_VAL == ECAN_LIB_MODE_FIXED) && (ECAN_FUNC_MODE_VAL == ECAN_MODE_2) )
  1029. static BYTE* _ECANPointBuffer(BYTE b)
  1030. {
  1031. BYTE* pt;
  1032. switch(b)
  1033. {
  1034. case 0:
  1035. pt=(BYTE*)&RXB0CON; // return pointer to correct buffer
  1036. break;
  1037. case 1:
  1038. pt=(BYTE*)&RXB1CON;
  1039. break;
  1040. case 2:
  1041. pt=(BYTE*)&B0CON;
  1042. break;
  1043. case 3:
  1044. pt=(BYTE*)&B1CON;
  1045. break;
  1046. case 4:
  1047. pt=(BYTE*)&B2CON;
  1048. break;
  1049. case 5:
  1050. pt=(BYTE*)&B3CON;
  1051. break;
  1052. case 6:
  1053. pt=(BYTE*)&B4CON;
  1054. break;
  1055. default: //case 7:
  1056. pt=(BYTE*)&B5CON;
  1057. break;
  1058. }
  1059. return (pt);
  1060. }
  1061. #endif