PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pic24_ecan.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 #include "pic24_ecan.h"
31 
32 // Only include if this module exists.
33 #if (NUM_ECAN_MODS >= 1)
34 
35 
36 // Documentation for this file. If the \file tag is not present,
37 // this file will not be documented.
38 // Note: place this comment below the #if NUM_ECAN_MODS so Doxygen
39 // will only see it once.
40 /** \file
41  * ECAN support functions. \see pic24_ecan.h for details.
42  */
43 
44 
45 
46 #ifndef ECAN_1TIME_CODE_DEFS
47 
48 /**
49 Format a standard data frame \em u8_n for TX
50 \param p_ecanmsg pointer to message buffer (ECANMSG* )
51 \param u16_id Standard Identifier (11-bit)
52 \param u8_len Number of data bytes in the message
53 */
54 
55 
56 void formatStandardDataFrameECAN (ECANMSG* p_ecanmsg, uint16_t u16_id, uint8_t u8_len) {
57  p_ecanmsg->w0.IDE = 0;
58  p_ecanmsg->w0.SRR = 0;
59  p_ecanmsg->w0.SID = u16_id;
60  p_ecanmsg->w1.EID17_6 = 0;
61  p_ecanmsg->w2.EID5_0 = 0;
62  p_ecanmsg->w2.RTR = 0;
63  p_ecanmsg->w2.RB1 = 0;
64  p_ecanmsg->w2.RB0 = 0;
65  p_ecanmsg->w2.DLC = u8_len; //length of the message
66 }
67 
68 
69 /**
70 Format an extended data frame \em u8_n for TX
71 \param p_ecanmsg pointer to message buffer (ECANMSG* )
72 \param u32_id Standard Identifier (11-bit)
73 \param u8_len Number of data bytes in the message
74 */
75 
76 void formatExtendedDataFrameECAN (ECANMSG* p_ecanmsg, uint32_t u32_id, uint8_t u8_len) {
77 
78  p_ecanmsg->w0.IDE = 1;
79  p_ecanmsg->w0.SRR = 0;
80  p_ecanmsg->w0.SID = (u32_id >> 18) & 0x7FF;
81  p_ecanmsg->w1.EID17_6 = (u32_id >> 6) & 0xFFF;
82  p_ecanmsg->w2.EID5_0 = u32_id & 0x3F;
83  p_ecanmsg->w2.RTR = 0;
84  p_ecanmsg->w2.RB1 = 0;
85  p_ecanmsg->w2.RB0 = 0;
86  p_ecanmsg->w2.DLC = u8_len; //length of the message
87 }
88 
89 /**
90 Extract the 29-bit message id from an extended data frame
91 \param p_ecanmsg pointer to RX message buffer (ECANMSG* )
92 \return 29-bit message id
93 */
94 
95 uint32_t getIdExtendedDataFrameECAN (ECANMSG* p_ecanmsg) {
96  uint32_t u32_id, u32_tmp;
97  u32_tmp = p_ecanmsg->w0.SID;
98  u32_id = u32_tmp << 18;
99  u32_tmp = p_ecanmsg->w1.EID17_6;
100  u32_id = u32_id | (u32_tmp << 6) | p_ecanmsg->w2.EID5_0;
101  return u32_id;
102 }
103 
104 #define ECAN_1TIME_CODE_DEFS
105 #endif
106 
107 
108 
109 /**
110 Clear full bit of buffer \em u8_bufNum
111 \param u8_bufNum buffer number of full bit to clear (0 to 31)
112 */
113 
114 void clrRxFullFlagECAN1(uint8_t u8_bufNum) {
115  u8_bufNum &= 0x1F; //0-31
116  if (u8_bufNum > 15) {
117  u8_bufNum = u8_bufNum - 16;
118  C1RXFUL2 = C1RXFUL2 & ~(1<<u8_bufNum);
119  } else {
120  C1RXFUL1 = C1RXFUL1 & ~(1<<u8_bufNum);
121  }
122 }
123 
124 /**
125 Get full bit of buffer \em u8_bufNum, zero if empty, non-zero if ull
126 \param u8_bufNum buffer number of full bit to read(0 to 31)
127 */
128 
130  u8_bufNum &= 0x1F; //0-31
131  if (u8_bufNum > 15) {
132  u8_bufNum = u8_bufNum - 16;
133  return(C1RXFUL2 & (1<<u8_bufNum));
134  } else {
135  return(C1RXFUL1 & (1<<u8_bufNum));
136  }
137 }
138 
139 /**
140 Operation: Clear all of the full and overflow RX flags.
141 */
143  C1RXFUL1=0x0000;
144  C1RXFUL2=0x0000;
145  C1RXOVF1=0x0000;
146  C1RXOVF2=0x0000;
147 }
148 
149 /**
150 Configure a buffer as either RX or TX buffer, only has to be done for first 8 buffers.
151 \param u8_bufNum buffer number (0 to 7)
152 \param u8_type buffer type (0 - receive, 1 transmit)
153 \param u8_priority only used for TX, priority (0-3)
154 */
155 void configTxRxBufferECAN1(uint8_t u8_bufNum, uint8_t u8_type, uint8_t u8_priority ) {
156  u8_bufNum &= 0x07; //0-7
157  switch (u8_bufNum) {
158  case 0:
159  C1TR01CONbits.TXEN0 = u8_type;
160  C1TR01CONbits.TX0PRI = u8_priority;
161  break;
162  case 1:
163  C1TR01CONbits.TXEN1 = u8_type;
164  C1TR01CONbits.TX1PRI = u8_priority;
165  break;
166  case 2:
167  C1TR23CONbits.TXEN2 = u8_type;
168  C1TR23CONbits.TX2PRI = u8_priority;
169  break;
170  case 3:
171  C1TR23CONbits.TXEN3 = u8_type;
172  C1TR23CONbits.TX3PRI = u8_priority;
173  break;
174  case 4:
175  C1TR45CONbits.TXEN4 = u8_type;
176  C1TR45CONbits.TX4PRI = u8_priority;
177  break;
178  case 5:
179  C1TR45CONbits.TXEN5 = u8_type;
180  C1TR45CONbits.TX5PRI = u8_priority;
181  break;
182  case 6:
183  C1TR67CONbits.TXEN6 = u8_type;
184  C1TR67CONbits.TX6PRI = u8_priority;
185  break;
186  default:
187  C1TR67CONbits.TXEN7 = u8_type;
188  C1TR67CONbits.TX7PRI = u8_priority;
189  break;
190  }
191 }
192 
193 /**
194 Start Transmit for buffer \em u8_bufNum
195 \param u8_bufNum buffer number (0 to 7)
196 **/
197 void startTxECAN1(uint8_t u8_bufNum) {
198  u8_bufNum &= 0x07; //0-7
199  switch (u8_bufNum) {
200  case 0:
201  C1TR01CONbits.TXREQ0 = 1;
202  break;
203  case 1:
204  C1TR01CONbits.TXREQ1 = 1;
205  break;
206  case 2:
207  C1TR23CONbits.TXREQ2 = 1;
208  break;
209  case 3:
210  C1TR23CONbits.TXREQ3 = 1;
211  break;
212  case 4:
213  C1TR45CONbits.TXREQ4 = 1;;
214  break;
215  case 5:
216  C1TR45CONbits.TXREQ5 = 1;
217  break;
218  case 6:
219  C1TR67CONbits.TXREQ6 = 1;
220  break;
221  default:
222  C1TR67CONbits.TXREQ7 = 1;
223  break;
224  }
225 }
226 
227 /**
228 Start Transmit for buffer \em u8_bufNum
229 \param u8_bufNum buffer number (0 to 7)
230 **/
232  u8_bufNum &= 0x07; //0-7
233  switch (u8_bufNum) {
234  case 0:
235  return(C1TR01CONbits.TXREQ0);
236  case 1:
237  return(C1TR01CONbits.TXREQ1);
238  case 2:
239  return(C1TR23CONbits.TXREQ2);
240  case 3:
241  return(C1TR23CONbits.TXREQ3);
242  case 4:
243  return(C1TR45CONbits.TXREQ4);
244  case 5:
245  return(C1TR45CONbits.TXREQ5);
246  case 6:
247  return(C1TR67CONbits.TXREQ6);
248  default:
249  return(C1TR67CONbits.TXREQ7);
250  }
251 }
252 
253 
254 
255 
256 /**
257 Configure an acceptance Filter
258 \param u8_filtNum filter number (0 to 15)
259 \param u32_id identifier, either SID (11 bits) or EID (29 bits)
260 \param u8_idType ID type (0: SID, nonzero: EID)
261 \param u8_bufnum RX buffer (0-14) to use for filter , if 15, then use FIFO
262 \param u8_maskReg Mask register (0-2) to use for filter
263 */
264 void configRxFilterECAN1(uint8_t u8_filtNum, uint32_t u32_id, uint8_t u8_idType, uint8_t u8_bufnum, uint8_t u8_maskReg) {
265  uint16_t *pu16_CxRXFySID,*pu16_CxRXFyEID, *pu16_CxFMSKSEL1, *pu16_CxBUFPNT1;
266  uint16_t u16_sid;
267  uint16_t u16_eid15_0;
268  uint16_t u16_eid17_16;
269  uint16_t u16_mask;
270  uint8_t u8_startPos;
271 
272  u8_filtNum &= 0xF; //0-15
273  u8_bufnum &= 0xF; //0-15
274  u8_maskReg &= 0x07; //0-7
275 
276  pu16_CxRXFySID = (uint16_t*) &C1RXF0SID + (u8_filtNum << 1);
277  pu16_CxRXFyEID = pu16_CxRXFySID + 1;
278  pu16_CxFMSKSEL1 = (uint16_t*) &C1FMSKSEL1 + (u8_filtNum >> 3);
279  pu16_CxBUFPNT1 = (uint16_t*) &C1BUFPNT1 + (u8_filtNum >> 2);
280 
281  C1CTRL1bits.WIN=1; //select filter register window
282 
283 //write to the CxRXFySID, CxRXFyEID registers
284  if(u8_idType) { // EID
285  u16_sid = (u32_id >> 18) & 0x7FF;
286  u16_eid17_16 = (u32_id >>16) & 0x3;
287  u16_eid15_0 = u32_id & 0xFFFF;
288  *pu16_CxRXFySID =(u16_sid <<5) | ECAN_MATCH_EID | u16_eid17_16;
289  *pu16_CxRXFyEID = u16_eid15_0;
290  } else { //SID
291  u16_sid = u32_id & 0x7FF;
292  *pu16_CxRXFySID = u16_sid <<5;
293  *pu16_CxRXFyEID = 0;
294  }
295 
296 //point the filter to the RX buffer (modify CxBUFPNT1 register)
297  u8_startPos = 4 * (u8_filtNum & 0x3); //starting bit position to mask
298  u16_mask = ~ ( 0xF << u8_startPos);
299  *pu16_CxBUFPNT1 = (*pu16_CxBUFPNT1 & u16_mask) | (u8_bufnum << u8_startPos);
300 
301 //point the filter to the mask register (modify CxFMSKSEL1 register)
302  u8_startPos = 2 * (u8_filtNum & 0x7);
303  u16_mask = ~ ( 0x3 << u8_startPos);
304  *pu16_CxFMSKSEL1 = (*pu16_CxFMSKSEL1 & u16_mask) | (u8_maskReg << u8_startPos);
305 
306  C1FEN1 = C1FEN1 | (1 << u8_filtNum) ; // Enable the filter
307 
308  C1CTRL1bits.WIN=0;
309 
310 }
311 
312 /**
313 Configure an acceptance MASK
314 \param u8_maskNum mask number (0 to 3; 0 to 2 specifies mask register, 3 then no mask is used)
315 \param u32_idMask mask for the identifier, either SID mask (11 bits) or EID mask (29 bits)
316 \param u8_idType ID type (0: SID, nonzero: EID)
317 \param u8_matchType Match type; if zero match either SID or EID addresses if filter matches
318 (i.e, match if (Filter SID == Message SID) || (Filter SID:EID = Message SID:EID)) )
319 If nonzero, match only message types as specified by the filter (either SID or SID:EID).
320 */
321 
322 void configRxMaskECAN1(uint8_t u8_maskNum, uint32_t u32_idMask, uint8_t u8_idType, uint8_t u8_matchType) {
323  uint16_t *pu16_CxRXMySID,*pu16_CxRXMyEID;
324  uint16_t u16_msid;
325  uint16_t u16_meid15_0;
326  uint16_t u16_meid17_16;
327 
328  pu16_CxRXMySID =(uint16_t*) &C1RXM0SID + (u8_maskNum << 1);
329  pu16_CxRXMyEID = pu16_CxRXMySID + 1;
330 
331  C1CTRL1bits.WIN=1; //select filter register window
332 
333 //write to the CxRXMySID, CxRXMyEID registers
334  if(u8_idType) { // EID
335  u16_msid = (u32_idMask >> 18) & 0x7FF;
336  u16_meid17_16 = (u32_idMask >>16) & 0x3;
337  u16_meid15_0 = u32_idMask & 0xFFFF;
338  if (u8_matchType) *pu16_CxRXMySID =(u16_msid <<5) | ECAN_MATCH_EID | u16_meid17_16;
339  else *pu16_CxRXMySID =(u16_msid <<5) | u16_meid17_16;
340  *pu16_CxRXMyEID = u16_meid15_0;
341  } else {
342  u16_msid = u32_idMask & 0x7FF;
343  if (u8_matchType) *pu16_CxRXMySID = (u16_msid <<5) | ECAN_MATCH_EID ;
344  else *pu16_CxRXMySID = (u16_msid <<5);
345  *pu16_CxRXMyEID = 0;
346  }
347  C1CTRL1bits.WIN=0;
348 }
349 
350 #endif // #if (NUM_ECAN_MODS >= ${x})
351 
352 
353 
354 
355 
356 
357 
358 
359 
360 
361 
362 
363 
364 /*
365  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
366  * All rights reserved.
367  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
368  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
369  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
370  *
371  * Permission to use, copy, modify, and distribute this software and its
372  * documentation for any purpose, without fee, and without written agreement is
373  * hereby granted, provided that the above copyright notice, the following
374  * two paragraphs and the authors appear in all copies of this software.
375  *
376  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
377  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
378  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
379  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
380  *
381  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
382  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
383  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
384  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
385  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
386  *
387  * Please maintain this header in its entirety when copying/modifying
388  * these files.
389  *
390  *
391  */
392 
393 #include "pic24_ecan.h"
394 
395 // Only include if this module exists.
396 #if (NUM_ECAN_MODS >= 2)
397 
398 
399 // Documentation for this file. If the \file tag is not present,
400 // this file will not be documented.
401 // Note: place this comment below the #if NUM_ECAN_MODS so Doxygen
402 // will only see it once.
403 /** \file
404  * ECAN support functions. \see pic24_ecan.h for details.
405  */
406 
407 
408 
409 #ifndef ECAN_1TIME_CODE_DEFS
410 
411 /**
412 Format a standard data frame \em u8_n for TX
413 \param p_ecanmsg pointer to message buffer (ECANMSG* )
414 \param u16_id Standard Identifier (11-bit)
415 \param u8_len Number of data bytes in the message
416 */
417 
418 
419 void formatStandardDataFrameECAN (ECANMSG* p_ecanmsg, uint16_t u16_id, uint8_t u8_len) {
420  p_ecanmsg->w0.IDE = 0;
421  p_ecanmsg->w0.SRR = 0;
422  p_ecanmsg->w0.SID = u16_id;
423  p_ecanmsg->w1.EID17_6 = 0;
424  p_ecanmsg->w2.EID5_0 = 0;
425  p_ecanmsg->w2.RTR = 0;
426  p_ecanmsg->w2.RB1 = 0;
427  p_ecanmsg->w2.RB0 = 0;
428  p_ecanmsg->w2.DLC = u8_len; //length of the message
429 }
430 
431 
432 /**
433 Format an extended data frame \em u8_n for TX
434 \param p_ecanmsg pointer to message buffer (ECANMSG* )
435 \param u32_id Standard Identifier (11-bit)
436 \param u8_len Number of data bytes in the message
437 */
438 
439 void formatExtendedDataFrameECAN (ECANMSG* p_ecanmsg, uint32_t u32_id, uint8_t u8_len) {
440 
441  p_ecanmsg->w0.IDE = 1;
442  p_ecanmsg->w0.SRR = 0;
443  p_ecanmsg->w0.SID = (u32_id >> 18) & 0x7FF;
444  p_ecanmsg->w1.EID17_6 = (u32_id >> 6) & 0xFFF;
445  p_ecanmsg->w2.EID5_0 = u32_id & 0x3F;
446  p_ecanmsg->w2.RTR = 0;
447  p_ecanmsg->w2.RB1 = 0;
448  p_ecanmsg->w2.RB0 = 0;
449  p_ecanmsg->w2.DLC = u8_len; //length of the message
450 }
451 
452 /**
453 Extract the 29-bit message id from an extended data frame
454 \param p_ecanmsg pointer to RX message buffer (ECANMSG* )
455 \return 29-bit message id
456 */
457 
458 uint32_t getIdExtendedDataFrameECAN (ECANMSG* p_ecanmsg) {
459  uint32_t u32_id, u32_tmp;
460  u32_tmp = p_ecanmsg->w0.SID;
461  u32_id = u32_tmp << 18;
462  u32_tmp = p_ecanmsg->w1.EID17_6;
463  u32_id = u32_id | (u32_tmp << 6) | p_ecanmsg->w2.EID5_0;
464  return u32_id;
465 }
466 
467 #define ECAN_1TIME_CODE_DEFS
468 #endif
469 
470 
471 
472 /**
473 Clear full bit of buffer \em u8_bufNum
474 \param u8_bufNum buffer number of full bit to clear (0 to 31)
475 */
476 
477 void clrRxFullFlagECAN2(uint8_t u8_bufNum) {
478  u8_bufNum &= 0x1F; //0-31
479  if (u8_bufNum > 15) {
480  u8_bufNum = u8_bufNum - 16;
481  C2RXFUL2 = C2RXFUL2 & ~(1<<u8_bufNum);
482  } else {
483  C2RXFUL1 = C2RXFUL1 & ~(1<<u8_bufNum);
484  }
485 }
486 
487 /**
488 Get full bit of buffer \em u8_bufNum, zero if empty, non-zero if ull
489 \param u8_bufNum buffer number of full bit to read(0 to 31)
490 */
491 
492 uint8_t getRxFullFlagECAN2(uint8_t u8_bufNum) {
493  u8_bufNum &= 0x1F; //0-31
494  if (u8_bufNum > 15) {
495  u8_bufNum = u8_bufNum - 16;
496  return(C2RXFUL2 & (1<<u8_bufNum));
497  } else {
498  return(C2RXFUL1 & (1<<u8_bufNum));
499  }
500 }
501 
502 /**
503 Operation: Clear all of the full and overflow RX flags.
504 */
505 void clrRxFullOvfFlagsECAN2(void) {
506  C2RXFUL1=0x0000;
507  C2RXFUL2=0x0000;
508  C2RXOVF1=0x0000;
509  C2RXOVF2=0x0000;
510 }
511 
512 /**
513 Configure a buffer as either RX or TX buffer, only has to be done for first 8 buffers.
514 \param u8_bufNum buffer number (0 to 7)
515 \param u8_type buffer type (0 - receive, 1 transmit)
516 \param u8_priority only used for TX, priority (0-3)
517 */
518 void configTxRxBufferECAN2(uint8_t u8_bufNum, uint8_t u8_type, uint8_t u8_priority ) {
519  u8_bufNum &= 0x07; //0-7
520  switch (u8_bufNum) {
521  case 0:
522  C2TR01CONbits.TXEN0 = u8_type;
523  C2TR01CONbits.TX0PRI = u8_priority;
524  break;
525  case 1:
526  C2TR01CONbits.TXEN1 = u8_type;
527  C2TR01CONbits.TX1PRI = u8_priority;
528  break;
529  case 2:
530  C2TR23CONbits.TXEN2 = u8_type;
531  C2TR23CONbits.TX2PRI = u8_priority;
532  break;
533  case 3:
534  C2TR23CONbits.TXEN3 = u8_type;
535  C2TR23CONbits.TX3PRI = u8_priority;
536  break;
537  case 4:
538  C2TR45CONbits.TXEN4 = u8_type;
539  C2TR45CONbits.TX4PRI = u8_priority;
540  break;
541  case 5:
542  C2TR45CONbits.TXEN5 = u8_type;
543  C2TR45CONbits.TX5PRI = u8_priority;
544  break;
545  case 6:
546  C2TR67CONbits.TXEN6 = u8_type;
547  C2TR67CONbits.TX6PRI = u8_priority;
548  break;
549  default:
550  C2TR67CONbits.TXEN7 = u8_type;
551  C2TR67CONbits.TX7PRI = u8_priority;
552  break;
553  }
554 }
555 
556 /**
557 Start Transmit for buffer \em u8_bufNum
558 \param u8_bufNum buffer number (0 to 7)
559 **/
560 void startTxECAN2(uint8_t u8_bufNum) {
561  u8_bufNum &= 0x07; //0-7
562  switch (u8_bufNum) {
563  case 0:
564  C2TR01CONbits.TXREQ0 = 1;
565  break;
566  case 1:
567  C2TR01CONbits.TXREQ1 = 1;
568  break;
569  case 2:
570  C2TR23CONbits.TXREQ2 = 1;
571  break;
572  case 3:
573  C2TR23CONbits.TXREQ3 = 1;
574  break;
575  case 4:
576  C2TR45CONbits.TXREQ4 = 1;;
577  break;
578  case 5:
579  C2TR45CONbits.TXREQ5 = 1;
580  break;
581  case 6:
582  C2TR67CONbits.TXREQ6 = 1;
583  break;
584  default:
585  C2TR67CONbits.TXREQ7 = 1;
586  break;
587  }
588 }
589 
590 /**
591 Start Transmit for buffer \em u8_bufNum
592 \param u8_bufNum buffer number (0 to 7)
593 **/
594 uint8_t getTxInProgressECAN2(uint8_t u8_bufNum) {
595  u8_bufNum &= 0x07; //0-7
596  switch (u8_bufNum) {
597  case 0:
598  return(C2TR01CONbits.TXREQ0);
599  case 1:
600  return(C2TR01CONbits.TXREQ1);
601  case 2:
602  return(C2TR23CONbits.TXREQ2);
603  case 3:
604  return(C2TR23CONbits.TXREQ3);
605  case 4:
606  return(C2TR45CONbits.TXREQ4);
607  case 5:
608  return(C2TR45CONbits.TXREQ5);
609  case 6:
610  return(C2TR67CONbits.TXREQ6);
611  default:
612  return(C2TR67CONbits.TXREQ7);
613  }
614 }
615 
616 
617 
618 
619 /**
620 Configure an acceptance Filter
621 \param u8_filtNum filter number (0 to 15)
622 \param u32_id identifier, either SID (11 bits) or EID (29 bits)
623 \param u8_idType ID type (0: SID, nonzero: EID)
624 \param u8_bufnum RX buffer (0-14) to use for filter , if 15, then use FIFO
625 \param u8_maskReg Mask register (0-2) to use for filter
626 */
627 void configRxFilterECAN2(uint8_t u8_filtNum, uint32_t u32_id, uint8_t u8_idType, uint8_t u8_bufnum, uint8_t u8_maskReg) {
628  uint16_t *pu16_CxRXFySID,*pu16_CxRXFyEID, *pu16_CxFMSKSEL1, *pu16_CxBUFPNT1;
629  uint16_t u16_sid;
630  uint16_t u16_eid15_0;
631  uint16_t u16_eid17_16;
632  uint16_t u16_mask;
633  uint8_t u8_startPos;
634 
635  u8_filtNum &= 0xF; //0-15
636  u8_bufnum &= 0xF; //0-15
637  u8_maskReg &= 0x07; //0-7
638 
639  pu16_CxRXFySID = (uint16_t*) &C2RXF0SID + (u8_filtNum << 1);
640  pu16_CxRXFyEID = pu16_CxRXFySID + 1;
641  pu16_CxFMSKSEL1 = (uint16_t*) &C2FMSKSEL1 + (u8_filtNum >> 3);
642  pu16_CxBUFPNT1 = (uint16_t*) &C2BUFPNT1 + (u8_filtNum >> 2);
643 
644  C2CTRL1bits.WIN=1; //select filter register window
645 
646 //write to the CxRXFySID, CxRXFyEID registers
647  if(u8_idType) { // EID
648  u16_sid = (u32_id >> 18) & 0x7FF;
649  u16_eid17_16 = (u32_id >>16) & 0x3;
650  u16_eid15_0 = u32_id & 0xFFFF;
651  *pu16_CxRXFySID =(u16_sid <<5) | ECAN_MATCH_EID | u16_eid17_16;
652  *pu16_CxRXFyEID = u16_eid15_0;
653  } else { //SID
654  u16_sid = u32_id & 0x7FF;
655  *pu16_CxRXFySID = u16_sid <<5;
656  *pu16_CxRXFyEID = 0;
657  }
658 
659 //point the filter to the RX buffer (modify CxBUFPNT1 register)
660  u8_startPos = 4 * (u8_filtNum & 0x3); //starting bit position to mask
661  u16_mask = ~ ( 0xF << u8_startPos);
662  *pu16_CxBUFPNT1 = (*pu16_CxBUFPNT1 & u16_mask) | (u8_bufnum << u8_startPos);
663 
664 //point the filter to the mask register (modify CxFMSKSEL1 register)
665  u8_startPos = 2 * (u8_filtNum & 0x7);
666  u16_mask = ~ ( 0x3 << u8_startPos);
667  *pu16_CxFMSKSEL1 = (*pu16_CxFMSKSEL1 & u16_mask) | (u8_maskReg << u8_startPos);
668 
669  C2FEN1 = C2FEN1 | (1 << u8_filtNum) ; // Enable the filter
670 
671  C2CTRL1bits.WIN=0;
672 
673 }
674 
675 /**
676 Configure an acceptance MASK
677 \param u8_maskNum mask number (0 to 3; 0 to 2 specifies mask register, 3 then no mask is used)
678 \param u32_idMask mask for the identifier, either SID mask (11 bits) or EID mask (29 bits)
679 \param u8_idType ID type (0: SID, nonzero: EID)
680 \param u8_matchType Match type; if zero match either SID or EID addresses if filter matches
681 (i.e, match if (Filter SID == Message SID) || (Filter SID:EID = Message SID:EID)) )
682 If nonzero, match only message types as specified by the filter (either SID or SID:EID).
683 */
684 
685 void configRxMaskECAN2(uint8_t u8_maskNum, uint32_t u32_idMask, uint8_t u8_idType, uint8_t u8_matchType) {
686  uint16_t *pu16_CxRXMySID,*pu16_CxRXMyEID;
687  uint16_t u16_msid;
688  uint16_t u16_meid15_0;
689  uint16_t u16_meid17_16;
690 
691  pu16_CxRXMySID =(uint16_t*) &C2RXM0SID + (u8_maskNum << 1);
692  pu16_CxRXMyEID = pu16_CxRXMySID + 1;
693 
694  C2CTRL1bits.WIN=1; //select filter register window
695 
696 //write to the CxRXMySID, CxRXMyEID registers
697  if(u8_idType) { // EID
698  u16_msid = (u32_idMask >> 18) & 0x7FF;
699  u16_meid17_16 = (u32_idMask >>16) & 0x3;
700  u16_meid15_0 = u32_idMask & 0xFFFF;
701  if (u8_matchType) *pu16_CxRXMySID =(u16_msid <<5) | ECAN_MATCH_EID | u16_meid17_16;
702  else *pu16_CxRXMySID =(u16_msid <<5) | u16_meid17_16;
703  *pu16_CxRXMyEID = u16_meid15_0;
704  } else {
705  u16_msid = u32_idMask & 0x7FF;
706  if (u8_matchType) *pu16_CxRXMySID = (u16_msid <<5) | ECAN_MATCH_EID ;
707  else *pu16_CxRXMySID = (u16_msid <<5);
708  *pu16_CxRXMyEID = 0;
709  }
710  C2CTRL1bits.WIN=0;
711 }
712 
713 #endif // #if (NUM_ECAN_MODS >= ${x})
714 
715 
716 
717 
718 
719 
720 
721 
722 
723 
724 
725 
726