BMS_ECAN.c 38 KB

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