| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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 */
47 STATIC void getSectionAddress(IP_CAN_001_AF_T *pCanAF,
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 */
67 STATIC INLINE uint16_t getTotalEntryNum(IP_CAN_001_AF_T *pCanAF)
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. */
73 STATIC INLINE void setSectionEndAddress(IP_CAN_001_AF_T *pCanAF,
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.*/
80 STATIC INLINE Status getReceiveFrameInfo(IP_CAN_001_T *pCAN,
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 */
88 STATIC INLINE void setSendFrameInfo(IP_CAN_001_T *pCAN, IP_CAN_BUFFER_ID_T TxBufID,
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;
98 Entry = (pEntryInfo->CtrlNo & CAN_STD_ENTRY_CTRL_NO_MASK) << CAN_STD_ENTRY_CTRL_NO_POS;
99 Entry |= (pEntryInfo->Disable & CAN_STD_ENTRY_DISABLE_MASK) << CAN_STD_ENTRY_DISABLE_POS;
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 {
109 return ((CtrlNo & CAN_STD_ENTRY_CTRL_NO_MASK) << CAN_STD_ENTRY_CTRL_NO_POS) | (1 << CAN_STD_ENTRY_DISABLE_POS);
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 */
121 STATIC Status setupSTDSection(uint32_t *pCanAFRamAddr,
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 */
160 STATIC Status setupSTDRangeSection(uint32_t *pCanAFRamAddr,
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];
202 CtrlNo = (curRow >> CAN_STD_ENTRY_CTRL_NO_POS) & CAN_STD_ENTRY_CTRL_NO_MASK;
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 */
218 STATIC uint32_t createExtIDEntry(IP_CAN_EXT_ID_Entry_T *pEntryInfo)
219 {
220 uint32_t Entry = 0;
221 Entry = (pEntryInfo->CtrlNo & CAN_EXT_ENTRY_CTRL_NO_MASK) << CAN_EXT_ENTRY_CTRL_NO_POS;
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 */
227 STATIC void readExtIDEntry(uint32_t EntryVal, IP_CAN_EXT_ID_Entry_T *pEntryInfo)
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 */
256 STATIC Status setupEXTRangeSection(uint32_t *pCanAFRamAddr,
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 */
332 void IP_CAN_Init(IP_CAN_001_T *pCAN) {
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 */
342 pCAN->CMR = CAN_CMR_RRB | CAN_CMR_AT | CAN_CMR_CDO;
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 */
352 void IP_CAN_SetMode(IP_CAN_001_T *pCAN, uint32_t Mode, FunctionalState NewState)
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 */
381 void IP_CAN_SetBusTiming(IP_CAN_001_T *pCAN, IP_CAN_BUS_TIMING_T *pBusTiming) {
382 /* Enter to Reset Mode */
383 IP_CAN_SetMode(pCAN, CAN_MOD_RM, ENABLE);
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 */
396 IP_CAN_SetMode(pCAN, CAN_MOD_RM, DISABLE);
397 }
398
399 /* Receive CAN Message */
400 Status IP_CAN_Receive(IP_CAN_001_T *pCAN, IP_CAN_MSG_T *pMsg) {
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 */
437 Status IP_CAN_Send(IP_CAN_001_T *pCAN, IP_CAN_BUFFER_ID_T TxBufID, IP_CAN_MSG_T *pMsg)
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 */
481 void IP_CAN_FullCANIntConfig(IP_CAN_001_AF_T *pCanAF, FunctionalState NewState)
482 {
483 uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
484
485 /* AF Off */
486 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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 */
500 uint32_t IP_CAN_GetFullCANIntStatus(IP_CAN_001_AF_T *pCanAF, uint8_t ObjID)
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 */
509 Status IP_CAN_FullCANReceive(IP_CAN_001_AF_T *pCanAF, IP_CAN_001_AF_RAM_T *pCanAFRam
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 */
518 if (((pSrc[0] >> CANAF_FULLCAN_MSG_SEM_POS) & CANAF_FULLCAN_MSG_SEM_BITMASK) !=
519 CANAF_FULCAN_MSG_AF_FINISHED) {
520 return ERROR;
521 }
522
523 /* Mark that CPU is handling message */
524 pSrc[0] = CANAF_FULCAN_MSG_CPU_READING << CANAF_FULLCAN_MSG_SEM_POS;
525
526 /* Read Message */
527 *pSCC = (pSrc[0] >> CANAF_FULLCAN_MSG_SCC_POS) & CANAF_FULLCAN_MSG_SCC_BITMASK;
528 pMsg->ID = (pSrc[0] >> CANAF_FULLCAN_MSG_ID11_POS) & CANAF_FULLCAN_MSG_ID11_BITMASK;
529 pMsg->Type = 0;
530 if (pSrc[0] & (1 << CANAF_FULLCAN_MSG_RTR_POS)) {
531 pMsg->Type = CAN_REMOTE_MSG;
532 }
533 pMsg->DLC = (pSrc[0] >> CANAF_FULLCAN_MSG_DLC_POS) & CANAF_FULLCAN_MSG_DLC_BITMASK;
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) !=
539 CANAF_FULCAN_MSG_CPU_READING) {
540 return ERROR;
541 }
542
543 return SUCCESS;
544 }
545
546 /* Initialize CAN AF */
547 void IP_CAN_AF_Init(IP_CAN_001_AF_T *pCanAF, IP_CAN_001_AF_RAM_T *pCanAFRam) {
548
549 IP_CAN_ClearAFLUT(pCanAF, pCanAFRam);
550 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_OPERATION);
551 }
552
553 /* Clear AF LUT */
554 void IP_CAN_ClearAFLUT(IP_CAN_001_AF_T *pCanAF, IP_CAN_001_AF_RAM_T *pCanAFRam) {
555 uint32_t i = 0;
556 uint32_t CurMode = IP_CAN_AF_GetMode(pCanAF);
557
558 /* AF Off */
559 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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 */
567 setSectionEndAddress(pCanAF, CANAF_RAM_FULLCAN_SEC, 0);
568 setSectionEndAddress(pCanAF, CANAF_RAM_SFF_SEC, 0);
569 setSectionEndAddress(pCanAF, CANAF_RAM_SFF_GRP_SEC, 0);
570 setSectionEndAddress(pCanAF, CANAF_RAM_EFF_SEC, 0);
571 setSectionEndAddress(pCanAF, CANAF_RAM_EFF_GRP_SEC, 0);
572
573 /* Return to previous mode */
574 IP_CAN_AF_SetMode(pCanAF, CurMode);
575 }
576
577 /* Set AF Lookup Table */
578 Status IP_CAN_SetAFLUT(IP_CAN_001_AF_T *pCanAF, IP_CAN_001_AF_RAM_T *pCanAFRam,
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 */
585 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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 */
666 uint16_t IP_CAN_GetEntriesNum(IP_CAN_001_AF_T *pCanAF, IP_CAN_001_AF_RAM_T *pCanAFRam,
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 */
697 Status IP_CAN_InsertSTDEntry(IP_CAN_001_AF_T *pCanAF,
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,
737 CAN_STD_ENTRY_ID_MASK,
738 sizeof(uint16_t));
739 if ((IDIndex == -1) || (IDIndex > EntryCnt )) {
740 return ERROR;
741 }
742
743 /* AF Off */
744 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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 */
809 Status IP_CAN_InsertFullCANEntry(IP_CAN_001_AF_T *pCanAF,
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 */
816 Status IP_CAN_InsertIndividualSTDEntry(IP_CAN_001_AF_T *pCanAF,
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 */
824 Status IP_CAN_InsertIndividualEXTEntry(IP_CAN_001_AF_T *pCanAF,
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,
849 CAN_EXT_ENTRY_ID_MASK,
850 sizeof(uint32_t));
851 if ((IDIndex == -1) || (IDIndex > EntryCnt )) {
852 return ERROR;
853 }
854
855 /* AF Off */
856 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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
880 Status IP_CAN_InsertGroupSTDEntry(IP_CAN_001_AF_T *pCanAF,
881 IP_CAN_001_AF_RAM_T *pCanAFRam,
882 IP_CAN_STD_ID_RANGE_Entry_T *pEntry)
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 */
947 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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
972 Status IP_CAN_InsertGroupEXTEntry(IP_CAN_001_AF_T *pCanAF,
973 IP_CAN_001_AF_RAM_T *pCanAFRam,
974 IP_CAN_EXT_ID_RANGE_Entry_T *pEntry)
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 */
1035 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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 */
1057 Status IP_CAN_RemoveSTDEntry(IP_CAN_001_AF_T *pCanAF,
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 */
1098 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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;
1113 CtrlNo = (tmp >> CAN_STD_ENTRY_CTRL_NO_POS) & CAN_STD_ENTRY_CTRL_NO_MASK;
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 */
1149 Status IP_CAN_RemoveLUTEntry(IP_CAN_001_AF_T *pCanAF,
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 */
1193 IP_CAN_AF_SetMode(pCanAF, CANAF_AFMR_ACCOFF);
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 */
1225 Status IP_CAN_RemoveFullCANEntry(IP_CAN_001_AF_T *pCanAF,
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 */
1232 Status IP_CAN_RemoveIndividualSTDEntry(IP_CAN_001_AF_T *pCanAF,
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 */
1240 Status IP_CAN_RemoveGroupSTDEntry(IP_CAN_001_AF_T *pCanAF,
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 */
1248 Status IP_CAN_RemoveIndividualEXTEntry(IP_CAN_001_AF_T *pCanAF,
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 */
1255 Status IP_CAN_RemoveGroupEXTEntry(IP_CAN_001_AF_T *pCanAF,
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 */
1263 Status IP_CAN_ReadSTDEntry(IP_CAN_001_AF_T *pCanAF,
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
1304 Status IP_CAN_ReadFullCANEntry(IP_CAN_001_AF_T *pCanAF,
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
1312 Status IP_CAN_ReadIndividualSTDEntry(IP_CAN_001_AF_T *pCanAF,
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
1320 Status IP_CAN_ReadGroupSTDEntry(IP_CAN_001_AF_T *pCanAF,
1321 IP_CAN_001_AF_RAM_T *pCanAFRam,
1322 uint16_t Position,
1323 IP_CAN_STD_ID_RANGE_Entry_T *pEntry)
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
1342 Status IP_CAN_ReadIndividualEXTEntry(IP_CAN_001_AF_T *pCanAF,
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
1363 Status IP_CAN_ReadGroupEXTEntry(IP_CAN_001_AF_T *pCanAF,
1364 IP_CAN_001_AF_RAM_T *pCanAFRam,
1365 uint16_t Position,
1366 IP_CAN_EXT_ID_RANGE_Entry_T *pEntry)
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 }