LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
can_001.c
Go to the documentation of this file.
1 /*
2  * @brief CAN Registers and control functions
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "can_001.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
37 
38 /*****************************************************************************
39  * Public types/enumerations/variables
40  ****************************************************************************/
41 
42 /*****************************************************************************
43  * Private functions
44  ****************************************************************************/
45 
46 /* Get start row, end row of the given section */
48  IP_CAN_AF_RAM_SECTION_T SectionID, uint16_t *StartAddr, uint16_t *EndAddr)
49 {
50  if (SectionID == CANAF_RAM_FULLCAN_SEC) {
51  *StartAddr = 0;
52  }
53  else {
54  *StartAddr = CANAF_ENDADDR_VAL(pCanAF->ENDADDR[SectionID - 1]);
55  }
56  *EndAddr = CANAF_ENDADDR_VAL(pCanAF->ENDADDR[SectionID]);
57 
58  if (*EndAddr > 0) {
59  *EndAddr -= 1; /* Minus 1 to get the actual end row */
60  }
61  else {
62  *EndAddr = *StartAddr;
63  }
64 }
65 
66 /* Get the total number of entries in LUT */
68 {
69  return CANAF_ENDADDR_VAL(pCanAF->ENDADDR[CANAF_RAM_EFF_GRP_SEC]); /* Extended ID Group section is the last section of LUT */
70 }
71 
72 /* Set the End Address of a section. EndAddr = the number of the last row of the section + 1. */
74  IP_CAN_AF_RAM_SECTION_T SectionID, uint16_t EndAddr)
75 {
76  pCanAF->ENDADDR[SectionID] = CANAF_ENDADDR(EndAddr);
77 }
78 
79 /* Get information of the received frame. Return ERROR means no message came.*/
81  IP_CAN_001_RX_T *pRxFrame)
82 {
83  *pRxFrame = pCAN->RX;
84  return (pCAN->SR & CAN_SR_RBS(0)) ? SUCCESS : ERROR;
85 }
86 
87 /* Set Tx Frame Information */
89  IP_CAN_001_TX_T *pTxFrame)
90 {
91  pCAN->TX[TxBufID] = *pTxFrame;
92 }
93 
94 /* Create the standard ID entry */
95 STATIC uint16_t createStdIDEntry(IP_CAN_STD_ID_Entry_T *pEntryInfo, bool IsFullCANEntry)
96 {
97  uint16_t Entry = 0;
100  Entry |= (pEntryInfo->ID_11 & CAN_STD_ENTRY_ID_MASK) << CAN_STD_ENTRY_ID_POS;
101  if (IsFullCANEntry) {
102  Entry |= 1 << CAN_STD_ENTRY_IE_POS;
103  }
104  return Entry;
105 }
106 
107 STATIC INLINE uint16_t createUnUsedSTDEntry(uint8_t CtrlNo)
108 {
110 }
111 
112 /* Get information from the standard ID entry */
113 STATIC void readStdIDEntry(uint16_t EntryVal, IP_CAN_STD_ID_Entry_T *pEntryInfo)
114 {
115  pEntryInfo->CtrlNo = (EntryVal >> CAN_STD_ENTRY_CTRL_NO_POS) & CAN_STD_ENTRY_CTRL_NO_MASK;
116  pEntryInfo->Disable = (EntryVal >> CAN_STD_ENTRY_DISABLE_POS) & CAN_STD_ENTRY_DISABLE_MASK;
117  pEntryInfo->ID_11 = (EntryVal >> CAN_STD_ENTRY_ID_POS) & CAN_STD_ENTRY_ID_MASK;
118 }
119 
120 /* Setup Standard iD section */
122  IP_CAN_STD_ID_Entry_T *pStdCANSec,
123  uint16_t EntryNum,
124  bool IsFullCANEntry)
125 {
126  uint16_t i;
127  uint16_t CurID = 0;
128  uint16_t Entry;
129  uint16_t EntryCnt = 0;
130 
131  /* Setup FullCAN section */
132  for (i = 0; i < EntryNum; i += 2) {
133  /* First Entry */
134  if (CurID > pStdCANSec[i].ID_11) {
135  return ERROR;
136  }
137  CurID = pStdCANSec[i].ID_11;
138  Entry = createStdIDEntry(&pStdCANSec[i], IsFullCANEntry);
139  pCanAFRamAddr[EntryCnt] = Entry << 16;
140 
141  /* Second Entry */
142  if ((i + 1) < EntryNum) {
143  if (CurID > pStdCANSec[i + 1].ID_11) {
144  return ERROR;
145  }
146  CurID = pStdCANSec[i + 1].ID_11;
147  Entry = createStdIDEntry(&pStdCANSec[i + 1], IsFullCANEntry);
148  pCanAFRamAddr[EntryCnt] |= Entry;
149  }
150  else {
151  pCanAFRamAddr[EntryCnt] |= createUnUsedSTDEntry(pStdCANSec[0].CtrlNo);
152  }
153  EntryCnt++;
154  }
155  return SUCCESS;
156 
157 }
158 
159 /* Setup the Group Standard ID section */
161  IP_CAN_STD_ID_RANGE_Entry_T *pStdRangeCANSec,
162  uint16_t EntryNum)
163 {
164  return setupSTDSection(pCanAFRamAddr, (IP_CAN_STD_ID_Entry_T *) pStdRangeCANSec, EntryNum * 2, false);
165 }
166 
167 /* Shift a number of entries down 1 position */
168 STATIC void shiftSTDEntryDown(uint32_t *arr, int32_t num)
169 {
170  uint32_t i = 0;
171  uint32_t prevRow, curRow;
172 
173  if (num <= 0) {
174  return;
175  }
176 
177  prevRow = arr[0];
178  arr[0] = ((prevRow & 0xFFFF0000) >> 16);
179  for (i = 0; i < (num / 2); i++) {
180  curRow = arr[i + 1];
181  arr[i + 1] = ((prevRow & 0xFFFF) << 16) | ((curRow & 0xFFFF0000) >> 16);
182  prevRow = curRow;
183  }
184  if ((num % 2) == 0) {
185  uint8_t CtrlNo = (prevRow >> CAN_STD_ENTRY_CTRL_NO_POS) & CAN_STD_ENTRY_CTRL_NO_MASK;
186  arr[num / 2] = ((prevRow & 0xFFFF) << 16) | createUnUsedSTDEntry(CtrlNo);
187  }
188 }
189 
190 /* Shift a number of entries up 1 position */
191 STATIC void shiftSTDEntryUp(uint32_t *arr, int32_t num)
192 {
193  int32_t i = 0;
194  uint32_t prevRow = 0, curRow = 0;
195  uint8_t CtrlNo = 0;
196 
197  if (num <= 0) {
198  return;
199  }
200 
201  curRow = arr[((num + 1) / 2) - 1];
203 
204  /* If num is odd, the last row only includes one item. Therefore, there is nothing
205  to do with it. If num is even, shift the last item to one place of the row.*/
206  if ((num % 2) == 0) {
207  arr[((num + 1) / 2) - 1] = ((curRow & 0xFFFF) << 16) | createUnUsedSTDEntry(CtrlNo);
208  }
209  /* Shift from the row before the last row */
210  for (i = ((num + 1) / 2) - 1; i > 0; i--) {
211  prevRow = arr[i - 1];
212  arr[i - 1] = ((curRow & 0xFFFF0000) >> 16) | ((prevRow & 0xFFFF) << 16);
213  curRow = prevRow;
214  }
215 }
216 
217 /* Create an extended ID entry */
219 {
220  uint32_t Entry = 0;
222  Entry |= (pEntryInfo->ID_29 & CAN_EXT_ENTRY_ID_MASK) << CAN_EXT_ENTRY_ID_POS;
223  return Entry;
224 }
225 
226 /* Get information from an extended ID entry */
228 {
229  pEntryInfo->CtrlNo = (EntryVal >> CAN_EXT_ENTRY_CTRL_NO_POS) & CAN_EXT_ENTRY_CTRL_NO_MASK;
230  pEntryInfo->ID_29 = (EntryVal >> CAN_EXT_ENTRY_ID_POS) & CAN_EXT_ENTRY_ID_MASK;
231 }
232 
233 /* Setup the Extended ID Section */
234 STATIC Status setupEXTSection(uint32_t *pCanAFRamAddr, IP_CAN_EXT_ID_Entry_T *pExtCANSec, uint16_t EntryNum)
235 {
236  uint16_t i;
237  uint32_t CurID = 0;
238  uint32_t Entry;
239  uint16_t EntryCnt = 0;
240 
241  /* Setup FullCAN section */
242  for (i = 0; i < EntryNum; i++) {
243  if (CurID > pExtCANSec[i].ID_29) {
244  return ERROR;
245  }
246  CurID = pExtCANSec[i].ID_29;
247  Entry = createExtIDEntry(&pExtCANSec[i]);
248  pCanAFRamAddr[EntryCnt] = Entry;
249  EntryCnt++;
250  }
251  return SUCCESS;
252 
253 }
254 
255 /* Setup Group Extended ID section */
257  IP_CAN_EXT_ID_RANGE_Entry_T *pExtRangeCANSec,
258  uint16_t EntryNum)
259 {
260  return setupEXTSection(pCanAFRamAddr, (IP_CAN_EXT_ID_Entry_T *) pExtRangeCANSec, EntryNum * 2);
261 }
262 
263 /* Get entry value from the given start index of the given array. byteNum is 2 or 4 bytes */
264 STATIC uint32_t getArrayVal(uint8_t *arr, uint32_t startIndex, uint8_t byteNum)
265 {
266  uint8_t i = 0;
267  uint32_t retVal = 0;
268  uint32_t index;
269 
270  index = startIndex * byteNum;
271  if (byteNum == 2) { // each entry uses 2 bytes
272  if (startIndex % 2) {
273  index -= 2; // little endian
274  }
275  else {
276  index += 2;
277  }
278  }
279 
280  for (i = 0; i < byteNum; i++) {
281  retVal |= arr[index + i] << (8 * i);
282  }
283  return retVal;
284 }
285 
286 /* Search the index to insert the new entry */
287 STATIC int32_t searchInsertIndex(uint32_t *arr, uint32_t arrNum, uint32_t val, uint32_t mask, uint8_t unitSize)
288 {
289  uint32_t LowerIndex, UpperIndex, MidIndex;
290  uint32_t MidVal;
291  uint8_t *byteArray = (uint8_t *) arr;
292 
293  if (arrNum == 0) {
294  return 0; /* Insert into the first line */
295 
296  }
297  LowerIndex = 0;
298  UpperIndex = arrNum - 1;
299  while (LowerIndex + 1 < UpperIndex) {
300  MidIndex = (LowerIndex + UpperIndex) / 2;
301  MidVal = getArrayVal(byteArray, MidIndex, unitSize) & mask;
302  if (MidVal == val) {
303  return -1; /* The new value is already in the array */
304  }
305  else if (MidVal < val) {
306  LowerIndex = MidIndex + 1;
307  }
308  else {
309  UpperIndex = MidIndex - 1;
310  }
311  }
312 
313  if (((getArrayVal(byteArray, LowerIndex, unitSize) & mask) == val) ||
314  ((getArrayVal(byteArray, UpperIndex, unitSize) & mask) == val)) {
315  return -1; /* The new value is already in the array */
316  }
317  if ((getArrayVal(byteArray, LowerIndex, unitSize) & mask) > val) {
318  return LowerIndex;
319  }
320  if ((getArrayVal(byteArray, UpperIndex, unitSize) & mask) < val) {
321  return UpperIndex + 1;
322  }
323 
324  return UpperIndex;
325 }
326 
327 /*****************************************************************************
328  * Public functions
329  ****************************************************************************/
330 
331 /* Initialize the the RTC peripheral */
333  volatile uint32_t i;
334  /* Enter to Reset Mode */
335  pCAN->MOD = CAN_MOD_RM;
336 
337  /* Disable all CAN Interrupts */
338  pCAN->IER &= (~CAN_IER_BITMASK) & CAN_IER_BITMASK;
339  pCAN->GSR &= (~CAN_GSR_BITMASK) & CAN_GSR_BITMASK;
340 
341  /* Request command to release Rx, Tx buffer and clear data overrun */
343 
344  /* Read to clear interrupt pending in interrupt capture register */
345  i = pCAN->ICR;
346 
347  /* Return to normal mode */
348  pCAN->MOD = CAN_MOD_OPERATION;
349 }
350 
351 /* Set CAN Mode */
353 {
354  if ((Mode & CAN_MOD_LOM) || (Mode & CAN_MOD_STM)) {
355  /* Enter to Reset Mode */
356  pCAN->MOD |= CAN_MOD_RM;
357 
358  /* Change to the given mode */
359  if (NewState) {
360  pCAN->MOD |= Mode;
361  }
362  else {
363  pCAN->MOD &= (~Mode) & CAN_MOD_BITMASK;
364  }
365 
366  /* Release Reset Mode */
367  pCAN->MOD &= (~CAN_MOD_RM) & CAN_MOD_BITMASK;
368  }
369  else {
370  if (NewState) {
371  pCAN->MOD |= Mode;
372  }
373  else {
374  pCAN->MOD &= (~Mode) & CAN_MOD_BITMASK;
375  }
376  }
377 
378 }
379 
380 /* Set Bus Timing */
382  /* Enter to Reset Mode */
384 
385  /* Set Bus Timing */
386  pCAN->BTR = CAN_BTR_BRP(pBusTiming->BRP)
387  | CAN_BTR_SJW(pBusTiming->SJW)
388  | CAN_BTR_TESG1(pBusTiming->TESG1)
389  | CAN_BTR_TESG2(pBusTiming->TESG2);
390 
391  if (pBusTiming->SAM) {
392  pCAN->BTR |= CAN_BTR_SAM;
393  }
394 
395  /* Exit from Reset Mode */
397 }
398 
399 /* Receive CAN Message */
401  int8_t i;
402  IP_CAN_001_RX_T RxFrame;
403  if (getReceiveFrameInfo(pCAN, &RxFrame) == SUCCESS) {
404 
405  /* Read Message Identifier */
406  if (RxFrame.RFS & CAN_RFS_FF) {
407  pMsg->ID = CAN_EXTEND_ID_USAGE | CAN_RID_ID_29(RxFrame.RID);
408  }
409  else {
410  pMsg->ID = CAN_RID_ID_11(RxFrame.RID);
411  }
412 
413  /* Read Data Length */
414  pMsg->DLC = CAN_RFS_DLC(RxFrame.RFS);
415 
416  /* Read Message Type */
417  pMsg->Type = 0;
418  if (RxFrame.RFS & CAN_RFS_RTR) {
419  pMsg->Type |= CAN_REMOTE_MSG;
420  }
421  else {
422  /* Read data only if the received message is not Remote message */
423  for (i = 0; i < CAN_MSG_MAX_DATA_LEN; i++) {
424  pMsg->Data[i] = (RxFrame.RD[i / 4] >> (8 * (i % 4))) & 0xFF;
425  }
426  }
427 
428  /* Release received message */
429  IP_CAN_SetCmd(pCAN, CAN_CMR_RRB);
430 
431  return SUCCESS;
432  }
433  return ERROR;
434 }
435 
436 /* Send CAN Message */
438 {
439  uint8_t i = 0;
440  IP_CAN_001_TX_T TxFrame;
441 
442  /* Write Frame Information */
443  TxFrame.TFI = 0;
444  if (pMsg->Type & CAN_REMOTE_MSG) {
445  TxFrame.TFI |= CAN_TFI_RTR;
446  }
447  else {
448  TxFrame.TFI |= CAN_TFI_DLC(pMsg->DLC);
449  for (i = 0; i < (CAN_MSG_MAX_DATA_LEN + 3) / 4; i++) {
450  TxFrame.TD[i] =
451  pMsg->Data[4 *
452  i] |
453  (pMsg->Data[4 * i +
454  1] << 8) | (pMsg->Data[4 * i + 2] << 16) | (pMsg->Data[4 * i + 3] << 24);
455  }
456  }
457 
458  if (pMsg->ID & CAN_EXTEND_ID_USAGE) {
459  TxFrame.TFI |= CAN_TFI_FF;
460  TxFrame.TID = CAN_TID_ID29(pMsg->ID);
461  }
462  else {
463  TxFrame.TID = CAN_TID_ID11(pMsg->ID);
464  }
465 
466  /* Set message information */
467  setSendFrameInfo(pCAN, TxBufID, &TxFrame);
468 
469  /* Select buffer and Write Transmission Request */
470  if (IP_CAN_GetMode(pCAN) == CAN_MOD_STM) {
471  IP_CAN_SetCmd(pCAN, CAN_CMR_STB(TxBufID) | CAN_CMR_SRR);
472  }
473  else {
474  IP_CAN_SetCmd(pCAN, CAN_CMR_STB(TxBufID) | CAN_CMR_TR);
475  }
476 
477  return SUCCESS;
478 }
479 
480 /* Enable/Disable FullCAN interrupt */
482 {
483  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
484 
485  /* AF Off */
487 
488  if (NewState == ENABLE) {
489  pCanAF->FCANIE |= CANAF_FCANIE;
490  }
491  else {
492  pCanAF->FCANIE &= (~CANAF_FCANIE) & CANAF_FCANIE_BITMASK;
493  }
494 
495  /* Return to previous mode */
496  IP_CAN_AF_SetMode(pCanAF, CurMode);
497 }
498 
499 /* Get interrupt status of the given object */
501 {
502  if (ObjID < 64) {
503  return (pCanAF->FCANIC[ObjID / 32] & (1 << (ObjID % 32))) ? SET : RESET;
504  }
505  return RESET;
506 }
507 
508 /* Read FullCAN message received */
510  , uint8_t ObjID, IP_CAN_MSG_T *pMsg, uint8_t *pSCC) {
511  uint32_t *pSrc;
512  uint16_t FullCANEntryCnt;
513  pSrc = (uint32_t *) pCanAFRam;
514 
515  FullCANEntryCnt = getTotalEntryNum(pCanAF);
516  pSrc += FullCANEntryCnt + ObjID * 3;
517  /* If the AF hasn't finished updating msg info */
520  return ERROR;
521  }
522 
523  /* Mark that CPU is handling message */
525 
526  /* Read Message */
529  pMsg->Type = 0;
530  if (pSrc[0] & (1 << CANAF_FULLCAN_MSG_RTR_POS)) {
531  pMsg->Type = CAN_REMOTE_MSG;
532  }
534  ((uint32_t *) pMsg->Data)[0] = pSrc[1];
535  ((uint32_t *) pMsg->Data)[1] = pSrc[2];
536 
537  /* Recheck message status to make sure data is not be updated while CPU is reading */
538  if (((pSrc[0] >> CANAF_FULLCAN_MSG_SEM_POS) & CANAF_FULLCAN_MSG_SEM_BITMASK) !=
540  return ERROR;
541  }
542 
543  return SUCCESS;
544 }
545 
546 /* Initialize CAN AF */
548 
549  IP_CAN_ClearAFLUT(pCanAF, pCanAFRam);
551 }
552 
553 /* Clear AF LUT */
555  uint32_t i = 0;
556  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
557 
558  /* AF Off */
560 
561  /* Clear AF Ram region */
562  for (i = 0; i < CANAF_RAM_ENTRY_NUM; i++) {
563  pCanAFRam->MASK[i] = 0;
564  }
565 
566  /* Reset address registers */
572 
573  /* Return to previous mode */
574  IP_CAN_AF_SetMode(pCanAF, CurMode);
575 }
576 
577 /* Set AF Lookup Table */
579  IP_CAN_AF_LUT_T *pAFSections) {
580  uint16_t EntryCnt = 0, FullCANEntryCnt = 0;
581  Status ret = ERROR;
582  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
583 
584  /* AF Off */
586 
587  do {
588  /* Check a number of entries */
589  if ((((pAFSections->FullCANEntryNum + 1) / 2) +
590  ((pAFSections->SffEntryNum + 1) / 2) +
591  (pAFSections->SffGrpEntryNum) +
592  (pAFSections->EffEntryNum) +
593  (pAFSections->EffGrpEntryNum * 2)) > CANAF_RAM_ENTRY_NUM) {
594  ret = ERROR;
595  break;
596  }
597 
598  /* Setup FullCAN section */
599  ret =
600  setupSTDSection((uint32_t *) &pCanAFRam->MASK[EntryCnt], pAFSections->FullCANSec,
601  pAFSections->FullCANEntryNum, true);
602  if (ret == ERROR) {
603  break;
604  }
605  EntryCnt = (pAFSections->FullCANEntryNum + 1) >> 1;
606  FullCANEntryCnt = EntryCnt;
607  setSectionEndAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, EntryCnt);
608 
609  /* Set up Individual Standard ID section */
610  ret =
611  setupSTDSection((uint32_t *) &pCanAFRam->MASK[EntryCnt],
612  pAFSections->SffSec,
613  pAFSections->SffEntryNum,
614  false);
615  if (ret == ERROR) {
616  break;
617  }
618 
619  EntryCnt += (pAFSections->SffEntryNum + 1) >> 1;
620  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_SEC, EntryCnt);
621 
622  /* Set up Group Standard ID section */
623  ret =
624  setupSTDRangeSection((uint32_t *) &pCanAFRam->MASK[EntryCnt], pAFSections->SffGrpSec,
625  pAFSections->SffGrpEntryNum);
626  if (ret == ERROR) {
627  break;
628  }
629 
630  EntryCnt += pAFSections->SffGrpEntryNum;
631  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, EntryCnt);
632 
633  /* Setup Individual Extended ID section */
634  ret =
635  setupEXTSection((uint32_t *) &pCanAFRam->MASK[EntryCnt], pAFSections->EffSec, pAFSections->EffEntryNum);
636  if (ret == ERROR) {
637  break;
638  }
639 
640  EntryCnt += pAFSections->EffEntryNum;
641  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_SEC, EntryCnt);
642 
643  /* Setup Group Extended ID section */
644  ret =
645  setupEXTRangeSection((uint32_t *) &pCanAFRam->MASK[EntryCnt], pAFSections->EffGrpSec,
646  pAFSections->EffGrpEntryNum);
647  if (ret == ERROR) {
648  break;
649  }
650 
651  EntryCnt += pAFSections->EffGrpEntryNum * 2;
652  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, EntryCnt);
653 
654  if ((FullCANEntryCnt > 0) && ((0x800 - 6 * FullCANEntryCnt) < EntryCnt)) {
655  ret = ERROR;
656  }
657 
658  } while (0);
659  /* Return to previous mode */
660  IP_CAN_AF_SetMode(pCanAF, CurMode);
661 
662  return ret;
663 }
664 
665 /* Get the number of entries of the given section */
667  IP_CAN_AF_RAM_SECTION_T SectionID)
668 {
669  uint16_t StartRow, EndRow;
670  uint16_t EntryCnt = 0;
671 
672  getSectionAddress(pCanAF, SectionID, &StartRow, &EndRow);
673  if (EndRow <= StartRow) {
674  return 0;
675  }
676  if ((SectionID == CANAF_RAM_FULLCAN_SEC) ||
677  (SectionID == CANAF_RAM_SFF_SEC)) {
678  EntryCnt = (EndRow - StartRow + 1) * 2;
679  if ((((pCanAFRam->MASK[EndRow] >> CAN_STD_ENTRY_ID_POS) & CAN_STD_ENTRY_ID_MASK) ==
680  0) &&
681  (((pCanAFRam->MASK[EndRow] >>
682  CAN_STD_ENTRY_DISABLE_POS) & CAN_STD_ENTRY_DISABLE_MASK) == 1)) { /* Unsed entry */
683  EntryCnt -= 1;
684  }
685  }
686  else if ((SectionID == CANAF_RAM_SFF_GRP_SEC) ||
687  (SectionID == CANAF_RAM_EFF_SEC)) {
688  EntryCnt = EndRow - StartRow + 1;
689  }
690  else {
691  EntryCnt = (EndRow - StartRow + 1) / 2;
692  }
693  return EntryCnt;
694 }
695 
696 /* Insert an entry into FullCAN Table */
698  IP_CAN_001_AF_RAM_T *pCanAFRam,
699  IP_CAN_STD_ID_Entry_T *pEntry,
700  bool IsFullCANEntry)
701 {
702  int32_t IDIndex = 0;
703  uint16_t StartRow, EndRow;
704  uint16_t EntryCnt = 0;
705  uint16_t i = 0;
706  uint32_t tmp = 0;
707  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
708 
709  if (getTotalEntryNum(pCanAF) >= CANAF_RAM_ENTRY_NUM) {
710  return ERROR;
711  }
712 
713  /* Check if a number of entries in section is odd or even */
714  if (IsFullCANEntry) {
715  getSectionAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, &StartRow, &EndRow);
716  }
717  else {
718  getSectionAddress(pCanAF, CANAF_RAM_SFF_SEC, &StartRow, &EndRow);
719 
720  }
721 
722  if (EndRow > StartRow) {
723  EntryCnt = (EndRow - StartRow + 1) * 2;
724  if ((((pCanAFRam->MASK[EndRow] >> CAN_STD_ENTRY_ID_POS) & CAN_STD_ENTRY_ID_MASK) ==
725  0) &&
726  (((pCanAFRam->MASK[EndRow] >>
727  CAN_STD_ENTRY_DISABLE_POS) & CAN_STD_ENTRY_DISABLE_MASK) == 1)) { /* Unsed entry */
728  EntryCnt -= 1;
729  }
730 
731  }
732 
733  /* Search for Index of new entry */
734  IDIndex = searchInsertIndex((uint32_t *) &pCanAFRam->MASK[StartRow],
735  EntryCnt,
736  pEntry->ID_11 & CAN_STD_ENTRY_ID_MASK,
738  sizeof(uint16_t));
739  if ((IDIndex == -1) || (IDIndex > EntryCnt )) {
740  return ERROR;
741  }
742 
743  /* AF Off */
745 
746  /* Move all remaining sections one place down
747  if new entry will increase FullCAN list */
748  if ((EntryCnt % 2) == 0) {
749  uint16_t StartAddr, EndAddr;
750 
751  for (i = getTotalEntryNum(pCanAF); i > EndRow; i--) {
752  pCanAFRam->MASK[i] = pCanAFRam->MASK[i - 1];
753  }
754 
755  if (IsFullCANEntry) {
756  getSectionAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, &StartAddr, &EndAddr);
757  setSectionEndAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, EndAddr + 2);
758  }
759  getSectionAddress(pCanAF, CANAF_RAM_SFF_SEC, &StartAddr, &EndAddr);
760  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_SEC, EndAddr + 2);
761  getSectionAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, &StartAddr, &EndAddr);
762  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, EndAddr + 2);
763  getSectionAddress(pCanAF, CANAF_RAM_EFF_SEC, &StartAddr, &EndAddr);
764  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_SEC, EndAddr + 2);
765  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartAddr, &EndAddr);
766  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, EndAddr + 2);
767  }
768 
769  /* Shift rows behind the row of search index. If search index is low index of the row, shift the row of search index also. */
770  if ((IDIndex % 2) == 0) {
771  shiftSTDEntryDown((uint32_t *) &pCanAFRam->MASK[StartRow + IDIndex / 2], EntryCnt - IDIndex);
772  }
773  else {
774  shiftSTDEntryDown((uint32_t *) &pCanAFRam->MASK[StartRow + IDIndex / 2 + 1], EntryCnt - IDIndex - 1);
775  }
776 
777  /* Insert new item */
778  tmp = createStdIDEntry(pEntry, IsFullCANEntry);
779  if ((IDIndex % 2) == 0) {
780  if (IDIndex == EntryCnt) {
781  /* Insert unused item if the new item is the last item*/
782  pCanAFRam->MASK[StartRow + IDIndex / 2] = (tmp << 16) | createUnUsedSTDEntry(pEntry->CtrlNo);
783  }
784  else {
785  uint32_t val;
786  val = pCanAFRam->MASK[StartRow + IDIndex / 2] & 0x0000FFFF;
787  /* Insert new item */
788  pCanAFRam->MASK[StartRow + IDIndex / 2] = val | (tmp << 16);
789  }
790  }
791  else {
792  uint32_t val, valNext;
793  val = pCanAFRam->MASK[StartRow + IDIndex / 2];
794  valNext = pCanAFRam->MASK[StartRow + IDIndex / 2 + 1];
795  /* In case the new entry is not the last item, shift the item at the found index to the next row*/
796  if (IDIndex < EntryCnt ) {
797 
798  pCanAFRam->MASK[StartRow + IDIndex / 2 + 1] = (valNext & 0x0000FFFF) | ((val & 0xFFFF) << 16);
799  }
800  pCanAFRam->MASK[StartRow + IDIndex / 2] = (val & 0xFFFF0000) | tmp;
801  }
802 
803  /* Return to previous mode */
804  IP_CAN_AF_SetMode(pCanAF, CurMode);
805  return SUCCESS;
806 }
807 
808 /* Insert an entry into FullCAN Table */
810  IP_CAN_001_AF_RAM_T *pCanAFRam,
811  IP_CAN_STD_ID_Entry_T *pEntry) {
812  return IP_CAN_InsertSTDEntry(pCanAF, pCanAFRam, pEntry, true);
813 }
814 
815 /* Insert an entry into Individual STD section */
817  IP_CAN_001_AF_RAM_T *pCanAFRam,
818  IP_CAN_STD_ID_Entry_T *pEntry)
819 {
820  return IP_CAN_InsertSTDEntry(pCanAF, pCanAFRam, pEntry, false);
821 }
822 
823 /* Insert an entry into Individual EXT section */
825  IP_CAN_001_AF_RAM_T *pCanAFRam,
826  IP_CAN_EXT_ID_Entry_T *pEntry) {
827  int32_t IDIndex = 0;
828  uint16_t StartRow, EndRow;
829  uint16_t EntryCnt = 0;
830  uint16_t i = 0;
831  uint32_t tmp = 0;
832  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
833 
834  if (getTotalEntryNum(pCanAF) >= CANAF_RAM_ENTRY_NUM) {
835  return ERROR;
836  }
837 
838  /* Check if a number of entries in section is odd or even */
839  getSectionAddress(pCanAF, CANAF_RAM_EFF_SEC, &StartRow, &EndRow);
840 
841  if (EndRow > StartRow) {
842  EntryCnt = EndRow - StartRow + 1;
843  }
844 
845  /* Search for Index of new entry */
846  IDIndex = searchInsertIndex((uint32_t *) &pCanAFRam->MASK[StartRow],
847  EntryCnt,
848  pEntry->ID_29 & CAN_EXT_ENTRY_ID_MASK,
850  sizeof(uint32_t));
851  if ((IDIndex == -1) || (IDIndex > EntryCnt )) {
852  return ERROR;
853  }
854 
855  /* AF Off */
857 
858  /* Move all remaining sections one place down
859  if new entry will increase FullCAN list */
860 
861  for (i = getTotalEntryNum(pCanAF); i > (StartRow + IDIndex); i--) {
862  pCanAFRam->MASK[i] = pCanAFRam->MASK[i - 1];
863  }
864 
865  /* Insert new item */
866  tmp = createExtIDEntry(pEntry);
867  pCanAFRam->MASK[StartRow + IDIndex] = tmp;
868 
869  /* Update address table */
870  getSectionAddress(pCanAF, CANAF_RAM_EFF_SEC, &StartRow, &EndRow);
871  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_SEC, EndRow + 2);
872  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartRow, &EndRow);
873  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, EndRow + 2);
874 
875  /* Return to previous mode */
876  IP_CAN_AF_SetMode(pCanAF, CurMode);
877  return SUCCESS;
878 }
879 
881  IP_CAN_001_AF_RAM_T *pCanAFRam,
883 {
884  uint16_t InsertIndex = 0;
885  uint16_t StartRow, EndRow;
886  uint16_t LowerID = 0, UpperID = 0;
887  uint16_t i = 0;
888  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
889 
890  if (getTotalEntryNum(pCanAF) >= CANAF_RAM_ENTRY_NUM) {
891  return ERROR;
892  }
893 
894  getSectionAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, &StartRow, &EndRow);
895 
896  /* Search for Index of the entry which upper the new item */
897  for (InsertIndex = StartRow; InsertIndex <= EndRow; InsertIndex++) {
898  LowerID = (pCanAFRam->MASK[InsertIndex] >> (16 + CAN_STD_ENTRY_ID_POS)) & CAN_STD_ENTRY_ID_MASK;
899  UpperID = (pCanAFRam->MASK[InsertIndex] >> CAN_STD_ENTRY_ID_POS) & CAN_STD_ENTRY_ID_MASK;
900  if (LowerID >= pEntry->LowerID.ID_11) {
901  break;
902  }
903  }
904 
905  /* Compare to the previous row (if any)*/
906  if (InsertIndex > 0) {
907  uint16_t PrevUpperID;
908  PrevUpperID = (pCanAFRam->MASK[InsertIndex - 1] >> CAN_STD_ENTRY_ID_POS) & CAN_STD_ENTRY_ID_MASK;
909 
910  if (PrevUpperID >= pEntry->UpperID.ID_11) {
911  return SUCCESS;
912  }
913 
914  if (pEntry->UpperID.ID_11 < LowerID) {
915  if (pEntry->LowerID.ID_11 < PrevUpperID) { /* The new range is merged to the range of the previous row */
916  uint32_t val = pCanAFRam->MASK[InsertIndex - 1] & 0xFFFF0000;
917  pCanAFRam->MASK[InsertIndex - 1] = val | createStdIDEntry(&pEntry->UpperID, false);
918  return SUCCESS;
919  }
920  else {
921  goto insert_grp_entry;
922  }
923  }
924  }
925 
926  /* Compare to the next row (if any)*/
927  if ((EndRow) && (InsertIndex <= EndRow)) {
928  if (pEntry->UpperID.ID_11 >= UpperID) { /* The new range is merged to the range of the next row */
929  uint32_t val;
930  val = createStdIDEntry(&pEntry->LowerID, false) << 16;
931  val |= createStdIDEntry(&pEntry->UpperID, false);
932  pCanAFRam->MASK[InsertIndex] = val;
933  return SUCCESS;
934  }
935  else if (pEntry->UpperID.ID_11 < UpperID) {
936  if (pEntry->UpperID.ID_11 > LowerID) { /* The new range is merged to the range of the next row */
937  uint32_t val = pCanAFRam->MASK[InsertIndex] & 0x0000FFFF;
938  pCanAFRam->MASK[InsertIndex] = val | (createStdIDEntry(&pEntry->LowerID, false) << 16);
939  return SUCCESS;
940  }
941  }
942  }
943 
944 insert_grp_entry:
945 
946  /* AF Off */
948 
949  /* Move all remaining sections one place down
950  if new entry will increase FullCAN list */
951 
952  for (i = getTotalEntryNum(pCanAF); i > InsertIndex; i--) {
953  pCanAFRam->MASK[i] = pCanAFRam->MASK[i - 1];
954  }
955 
956  /* Insert new item */
957  pCanAFRam->MASK[InsertIndex] = createStdIDEntry(&pEntry->LowerID, false) << 16;
958  pCanAFRam->MASK[InsertIndex] |= createStdIDEntry(&pEntry->UpperID, false);
959 
960  getSectionAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, &StartRow, &EndRow);
961  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, EndRow + 2);
962  getSectionAddress(pCanAF, CANAF_RAM_EFF_SEC, &StartRow, &EndRow);
963  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_SEC, EndRow + 2);
964  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartRow, &EndRow);
965  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, EndRow + 2);
966 
967  /* Return to previous mode */
968  IP_CAN_AF_SetMode(pCanAF, CurMode);
969  return SUCCESS;
970 }
971 
973  IP_CAN_001_AF_RAM_T *pCanAFRam,
975 {
976  uint32_t InsertIndex = 0;
977  uint16_t StartRow, EndRow;
978  uint32_t LowerID = 0, UpperID = 0;
979  uint16_t i = 0;
980  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
981 
982  if (getTotalEntryNum(pCanAF) >= CANAF_RAM_ENTRY_NUM) {
983  return ERROR;
984  }
985 
986  /* Check if a number of entries in section is odd or even */
987  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartRow, &EndRow);
988 
989  /* Search for Index of new entry */
990  for (InsertIndex = StartRow; InsertIndex <= EndRow; InsertIndex += 2) {
991  LowerID = (pCanAFRam->MASK[InsertIndex] >> CAN_EXT_ENTRY_ID_POS) & CAN_EXT_ENTRY_ID_MASK;
992  UpperID = (pCanAFRam->MASK[InsertIndex + 1] >> CAN_EXT_ENTRY_ID_POS) & CAN_EXT_ENTRY_ID_MASK;
993  if (LowerID >= pEntry->LowerID.ID_29) {
994  break;
995  }
996  }
997 
998  /* Compare to the previous row (if any)*/
999  if (InsertIndex > 0) {
1000  uint32_t PrevUpperID;
1001  PrevUpperID = (pCanAFRam->MASK[(InsertIndex - 2) + 1] >> CAN_EXT_ENTRY_ID_POS) & CAN_EXT_ENTRY_ID_MASK;
1002 
1003  if (PrevUpperID >= pEntry->UpperID.ID_29) {
1004  return SUCCESS;
1005  }
1006 
1007  if (pEntry->UpperID.ID_29 < LowerID) {
1008  if (pEntry->LowerID.ID_29 < PrevUpperID) {
1009  pCanAFRam->MASK[(InsertIndex - 2) + 1] = createExtIDEntry(&pEntry->UpperID);
1010  return SUCCESS;
1011  }
1012  else {
1013  goto insert_grp_entry;
1014  }
1015  }
1016  }
1017 
1018  if ((EndRow) && (InsertIndex < EndRow)) {
1019  if (pEntry->UpperID.ID_29 >= UpperID) {
1020  pCanAFRam->MASK[InsertIndex] = createExtIDEntry(&pEntry->LowerID);
1021  pCanAFRam->MASK[InsertIndex + 1] = createExtIDEntry(&pEntry->UpperID);
1022  return SUCCESS;
1023  }
1024  else if (pEntry->UpperID.ID_29 < UpperID) {
1025  if (pEntry->UpperID.ID_29 > LowerID) {
1026  pCanAFRam->MASK[InsertIndex] = createExtIDEntry(&pEntry->LowerID);
1027  return SUCCESS;
1028  }
1029  }
1030  }
1031 
1032 insert_grp_entry:
1033 
1034  /* AF Off */
1036 
1037  /* Move all remaining sections two places down
1038  if new entry will increase FullCAN list */
1039 
1040  for (i = getTotalEntryNum(pCanAF) + 1; i > InsertIndex; i--) {
1041  pCanAFRam->MASK[i] = pCanAFRam->MASK[i - 2];
1042  }
1043 
1044  /* Insert new item */
1045  pCanAFRam->MASK[InsertIndex] = createExtIDEntry(&pEntry->LowerID);
1046  pCanAFRam->MASK[InsertIndex + 1] = createExtIDEntry(&pEntry->UpperID);
1047 
1048  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartRow, &EndRow);
1049  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, EndRow + 3);
1050 
1051  /* Return to previous mode */
1052  IP_CAN_AF_SetMode(pCanAF, CurMode);
1053  return SUCCESS;
1054 }
1055 
1056 /* Remove STD Entry from given table */
1058  IP_CAN_001_AF_RAM_T *pCanAFRam,
1059  int16_t IDIndex,
1060  bool IsFullCANEntry)
1061 {
1062  uint16_t StartRow, EndRow;
1063  uint16_t EntryCnt = 0, i;
1064  uint32_t tmp = 0;
1065  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
1066 
1067  if (IDIndex < 0) {
1068  return ERROR;
1069  }
1070 
1071  if (getTotalEntryNum(pCanAF) >= CANAF_RAM_ENTRY_NUM) {
1072  return ERROR;
1073  }
1074 
1075  /* Check if a number of entries in section is odd or even */
1076  if (IsFullCANEntry) {
1077  getSectionAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, &StartRow, &EndRow);
1078  }
1079  else {
1080  getSectionAddress(pCanAF, CANAF_RAM_SFF_SEC, &StartRow, &EndRow);
1081  }
1082 
1083  if (EndRow > StartRow) {
1084  EntryCnt = (EndRow - StartRow + 1) * 2;
1085  if ((((pCanAFRam->MASK[EndRow] >> CAN_STD_ENTRY_ID_POS) & CAN_STD_ENTRY_ID_MASK) ==
1086  0) &&
1087  (((pCanAFRam->MASK[EndRow] >>
1088  CAN_STD_ENTRY_DISABLE_POS) & CAN_STD_ENTRY_DISABLE_MASK) == 1)) { /* Unsed entry */
1089  EntryCnt -= 1;
1090  }
1091 
1092  }
1093  if (IDIndex >= EntryCnt) {
1094  return ERROR;
1095  }
1096 
1097  /* AF Off */
1099 
1100  /* Shift rows behind the row of remove index. If remove index is low index of the row, shift the row of remove index also. */
1101  tmp = pCanAFRam->MASK[StartRow + IDIndex / 2 + 1];
1102  if ((IDIndex % 2) == 0) {
1103  shiftSTDEntryUp((uint32_t *) &pCanAFRam->MASK[StartRow + IDIndex / 2], EntryCnt - IDIndex);
1104  }
1105  else {
1106  shiftSTDEntryUp((uint32_t *) &pCanAFRam->MASK[StartRow + IDIndex / 2 + 1], EntryCnt - IDIndex - 1);
1107 
1108  /* Set value for the entry at remove index */
1109  pCanAFRam->MASK[StartRow + IDIndex / 2] &= 0xFFFF0000;
1110  if (IDIndex == (EntryCnt - 1)) {
1111  uint8_t CtrlNo;
1112  tmp = (pCanAFRam->MASK[StartRow + IDIndex / 2]) >> 16;
1114  pCanAFRam->MASK[StartRow + IDIndex / 2] |= createUnUsedSTDEntry(CtrlNo);
1115  }
1116  else {
1117  pCanAFRam->MASK[StartRow + IDIndex / 2] |= (tmp >> 16) & 0xFFFF;
1118  }
1119  }
1120  /* Move all remaining sections one place up
1121  if new entry will decrease FullCAN list */
1122  if (EntryCnt % 2) {
1123  uint16_t StartAddr, EndAddr;
1124 
1125  for (i = EndRow; i < getTotalEntryNum(pCanAF); i++) {
1126  pCanAFRam->MASK[i] = pCanAFRam->MASK[i + 1];
1127  }
1128 
1129  if (IsFullCANEntry) {
1130  getSectionAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, &StartAddr, &EndAddr);
1131  setSectionEndAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, EndAddr);
1132  }
1133  getSectionAddress(pCanAF, CANAF_RAM_SFF_SEC, &StartAddr, &EndAddr);
1134  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_SEC, EndAddr);
1135  getSectionAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, &StartAddr, &EndAddr);
1136  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, EndAddr);
1137  getSectionAddress(pCanAF, CANAF_RAM_EFF_SEC, &StartAddr, &EndAddr);
1138  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_SEC, EndAddr);
1139  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartAddr, &EndAddr);
1140  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, EndAddr);
1141  }
1142 
1143  /* Return to previous mode */
1144  IP_CAN_AF_SetMode(pCanAF, CurMode);
1145  return SUCCESS;
1146 }
1147 
1148 /* Remove LUT Entry from given table */
1150  IP_CAN_001_AF_RAM_T *pCanAFRam,
1151  IP_CAN_AF_RAM_SECTION_T SectionID,
1152  int16_t Position)
1153 {
1154  uint16_t StartRow, EndRow;
1155  uint16_t StartAddr, EndAddr;
1156  uint16_t EntryCnt = 0;
1157  uint8_t EntryRowNum = 1;
1158  uint16_t i = 0;
1159  uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
1160 
1161  if (Position < 0) {
1162  return ERROR;
1163  }
1164 
1165  if (getTotalEntryNum(pCanAF) >= CANAF_RAM_ENTRY_NUM) {
1166  return ERROR;
1167  }
1168 
1169  if (SectionID == CANAF_RAM_FULLCAN_SEC) {
1170  return IP_CAN_RemoveSTDEntry(pCanAF, pCanAFRam, Position, true);
1171  }
1172  else if (SectionID == CANAF_RAM_SFF_SEC) {
1173  return IP_CAN_RemoveSTDEntry(pCanAF, pCanAFRam, Position, false);
1174  }
1175 
1176  /* Get a number of rows for an entry */
1177  if (SectionID == CANAF_RAM_EFF_GRP_SEC) {
1178  EntryRowNum = 2;
1179  }
1180 
1181  /* Get Start Row, End Row */
1182  getSectionAddress(pCanAF, SectionID, &StartRow, &EndRow);
1183 
1184  if (EndRow > StartRow) {
1185  EntryCnt = (EndRow - StartRow + 1) / EntryRowNum;
1186  }
1187 
1188  if (Position >= EntryCnt) {
1189  return ERROR;
1190  }
1191 
1192  /* AF Off */
1194 
1195  /* Move all remaining sections one place up
1196  if new entry will increase FullCAN list */
1197  for (i = StartRow + Position * EntryRowNum; i < getTotalEntryNum(pCanAF); i++) {
1198  pCanAFRam->MASK[i] = pCanAFRam->MASK[i + EntryRowNum];
1199  }
1200 
1201  /* Get Start Row, End Row */
1202  switch (SectionID) {
1203  case CANAF_RAM_SFF_GRP_SEC:
1204  getSectionAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, &StartAddr, &EndAddr);
1205  setSectionEndAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, EndAddr - EntryRowNum + 1);
1206 
1207  case CANAF_RAM_EFF_SEC:
1208  getSectionAddress(pCanAF, CANAF_RAM_EFF_SEC, &StartAddr, &EndAddr);
1209  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_SEC, EndAddr - EntryRowNum + 1);
1210 
1211  case CANAF_RAM_EFF_GRP_SEC:
1212  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartAddr, &EndAddr);
1213  setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, EndAddr - EntryRowNum + 1);
1214  break;
1215  default:
1216  return ERROR;
1217  }
1218 
1219  /* Return to previous mode */
1220  IP_CAN_AF_SetMode(pCanAF, CurMode);
1221  return SUCCESS;
1222 }
1223 
1224 /* Remove an entry into FullCAN Table */
1226  IP_CAN_001_AF_RAM_T *pCanAFRam,
1227  int16_t Position) {
1228  return IP_CAN_RemoveLUTEntry(pCanAF, pCanAFRam, CANAF_RAM_FULLCAN_SEC, Position);
1229 }
1230 
1231 /* Remove an entry into Individual STD section */
1233  IP_CAN_001_AF_RAM_T *pCanAFRam,
1234  int16_t Position)
1235 {
1236  return IP_CAN_RemoveLUTEntry(pCanAF, pCanAFRam, CANAF_RAM_SFF_SEC, Position);
1237 }
1238 
1239 /* Remove an entry into Group STD section */
1241  IP_CAN_001_AF_RAM_T *pCanAFRam,
1242  int16_t Position)
1243 {
1244  return IP_CAN_RemoveLUTEntry(pCanAF, pCanAFRam, CANAF_RAM_SFF_GRP_SEC, Position);
1245 }
1246 
1247 /* Remove an entry into Individual EXT section */
1249  IP_CAN_001_AF_RAM_T *pCanAFRam,
1250  int16_t Position) {
1251  return IP_CAN_RemoveLUTEntry(pCanAF, pCanAFRam, CANAF_RAM_EFF_SEC, Position);
1252 }
1253 
1254 /* Remove an entry into Group EXT section */
1256  IP_CAN_001_AF_RAM_T *pCanAFRam,
1257  int16_t Position)
1258 {
1259  return IP_CAN_RemoveLUTEntry(pCanAF, pCanAFRam, CANAF_RAM_EFF_GRP_SEC, Position);
1260 }
1261 
1262 /* Read STD Entry */
1264  IP_CAN_001_AF_RAM_T *pCanAFRam,
1265  uint16_t Position,
1266  bool IsFullCANEntry,
1267  IP_CAN_STD_ID_Entry_T *pEntry)
1268 
1269 {
1270  uint16_t StartRow, EndRow;
1271  uint16_t EntryCnt = 0;
1272 
1273  /* Check if a number of entries in section is odd or even */
1274  if (IsFullCANEntry) {
1275  getSectionAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, &StartRow, &EndRow);
1276  }
1277  else {
1278  getSectionAddress(pCanAF, CANAF_RAM_SFF_SEC, &StartRow, &EndRow);
1279  }
1280 
1281  if (EndRow > StartRow) {
1282  EntryCnt = (EndRow - StartRow + 1) * 2;
1283  if ((((pCanAFRam->MASK[EndRow] >> CAN_STD_ENTRY_ID_POS) & CAN_STD_ENTRY_ID_MASK) ==
1284  0) &&
1285  (((pCanAFRam->MASK[EndRow] >>
1286  CAN_STD_ENTRY_DISABLE_POS) & CAN_STD_ENTRY_DISABLE_MASK) == 1)) { /* Unsed entry */
1287  EntryCnt -= 1;
1288  }
1289  }
1290  if (Position >= EntryCnt) {
1291  return ERROR;
1292  }
1293 
1294  if ((Position % 2) == 0) {
1295  readStdIDEntry(pCanAFRam->MASK[StartRow + Position / 2] >> 16, pEntry);
1296  }
1297  else {
1298  readStdIDEntry(pCanAFRam->MASK[StartRow + Position / 2] & 0xFFFF, pEntry);
1299  }
1300 
1301  return SUCCESS;
1302 }
1303 
1305  IP_CAN_001_AF_RAM_T *pCanAFRam,
1306  uint16_t Position,
1307  IP_CAN_STD_ID_Entry_T *pEntry)
1308 {
1309  return IP_CAN_ReadSTDEntry(pCanAF, pCanAFRam, Position, true, pEntry);
1310 }
1311 
1313  IP_CAN_001_AF_RAM_T *pCanAFRam,
1314  uint16_t Position,
1315  IP_CAN_STD_ID_Entry_T *pEntry)
1316 {
1317  return IP_CAN_ReadSTDEntry(pCanAF, pCanAFRam, Position, false, pEntry);
1318 }
1319 
1321  IP_CAN_001_AF_RAM_T *pCanAFRam,
1322  uint16_t Position,
1324 {
1325  uint16_t StartRow, EndRow;
1326  uint16_t EntryCnt = 0;
1327 
1328  getSectionAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, &StartRow, &EndRow);
1329 
1330  if (EndRow > StartRow) {
1331  EntryCnt = EndRow - StartRow + 1;
1332  }
1333  if (Position >= EntryCnt) {
1334  return ERROR;
1335  }
1336 
1337  readStdIDEntry(pCanAFRam->MASK[StartRow + Position] >> 16, &pEntry->LowerID);
1338  readStdIDEntry(pCanAFRam->MASK[StartRow + Position] & 0xFFFF, &pEntry->UpperID);
1339  return SUCCESS;
1340 }
1341 
1343  IP_CAN_001_AF_RAM_T *pCanAFRam,
1344  uint16_t Position,
1345  IP_CAN_EXT_ID_Entry_T *pEntry)
1346 {
1347  uint16_t StartRow, EndRow;
1348  uint16_t EntryCnt = 0;
1349 
1350  getSectionAddress(pCanAF, CANAF_RAM_EFF_SEC, &StartRow, &EndRow);
1351 
1352  if (EndRow > StartRow) {
1353  EntryCnt = EndRow - StartRow + 1;
1354  }
1355  if (Position >= EntryCnt) {
1356  return ERROR;
1357  }
1358 
1359  readExtIDEntry(pCanAFRam->MASK[StartRow + Position], pEntry);
1360  return SUCCESS;
1361 }
1362 
1364  IP_CAN_001_AF_RAM_T *pCanAFRam,
1365  uint16_t Position,
1367 
1368 {
1369  uint16_t StartRow, EndRow;
1370  uint16_t EntryCnt = 0;
1371 
1372  getSectionAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, &StartRow, &EndRow);
1373 
1374  if (EndRow > StartRow) {
1375  EntryCnt = (EndRow - StartRow + 1) / 2;
1376  }
1377  if (Position >= EntryCnt) {
1378  return ERROR;
1379  }
1380 
1381  readExtIDEntry(pCanAFRam->MASK[StartRow + Position * 2], &pEntry->LowerID);
1382  readExtIDEntry(pCanAFRam->MASK[StartRow + Position * 2 + 1], &pEntry->UpperID);
1383  return SUCCESS;
1384 }