iLLD_TC29x  1.0
IfxMtu.c
Go to the documentation of this file.
1 /**
2  * \file IfxMtu.c
3  * \brief MTU basic functionality
4  *
5  * \version iLLD_1_0_0_11_0
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  *
24  */
25 
26 /******************************************************************************/
27 /*----------------------------------Includes----------------------------------*/
28 /******************************************************************************/
29 
30 #include "IfxMtu.h"
31 
32 /** \addtogroup IfxLld_Mtu_Std_Utility
33  * \{ */
34 
35 /******************************************************************************/
36 /*-----------------------Private Function Prototypes--------------------------*/
37 /******************************************************************************/
38 
39 /** \brief API to wait for requested tower depth.
40  * \param towerDepth tower depth of MBIST Ram
41  * \param numInstructions number of instructions
42  * \param mbistSel Memory Selection
43  * \return None
44  */
45 static void IfxMtu_waitForMbistDone(uint32 towerDepth, uint8 numInstructions, IfxMtu_MbistSel mbistSel);
46 
47 /** \} */
48 
49 /******************************************************************************/
50 /*-------------------------Function Implementations---------------------------*/
51 /******************************************************************************/
52 
54 {
55  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
56  mc->ECCD.U |= (1 << IFX_MC_ECCD_TRC_OFF);
57 }
58 
59 
61 {
62  uint8 isEndInitEnabled = 0;
63  uint16 password = 0;
64 
66 
67  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
69  {
70  /* Clear EndInit */
72  isEndInitEnabled = 1;
73  }
74 
75  IfxMtu_clearSramStart(mbistSel);
76 
77  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
79 
80  /* wait for the end of the fill operation */
81  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
82  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 1, mbistSel);
83  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
84 
85  while (!IfxMtu_isMbistDone(mbistSel))
86  {
87  __nop();
88  }
89 
90  /* Clear EndInit */
92 
93  IfxMtu_clearSramContinue(mbistSel);
94 
95  if (isEndInitEnabled == 1)
96  {
97  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
99  }
100 }
101 
102 
104 {
105  /* Before clearing the ECC error flags we've to issue a dummy SRAM access to get a valid memory output */
106  IfxMtu_readSramAddress(mbistSel, 0x0000);
107 
108  /* Note: a SMU alarm will be flagged HERE if the wrong ECC has been written! */
109  IfxMtu_disableMbistShell(mbistSel);
110 
111  /* for auto-init memories: wait for the end of the clear operation */
112  while (IfxMtu_isAutoInitRunning(mbistSel))
113  {}
114 }
115 
116 
118 {
119  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
120 
121  IfxMtu_enableMbistShell(mbistSel);
122 
123  /* for auto-init memories: wait for the end of the clear operation */
124  while (IfxMtu_isAutoInitRunning(mbistSel))
125  {}
126 
127  /* write valid ECC code for all-zero data into RDBFL registers */
128  {
130  const IfxMtu_SramItem *item = (IfxMtu_SramItem *)&IfxMtu_sramTable[mbistSel];
131 
132  uint8 numBlocks = item->numBlocks;
133  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, numBlocks > 0);
134 
135  uint16 dataSize = item->dataSize;
136  uint8 eccSize = item->eccSize;
137  uint32 eccInvPos0 = dataSize + item->eccInvPos0;
138  uint32 eccInvPos1 = dataSize + item->eccInvPos1;
139 
140  uint32 memSize = dataSize + eccSize;
141 
142  uint32 bitPos = 0;
143  uint32 wordIx = 0;
144  uint16 data = 0;
145  /* de-serialize data stream into 16bit packets */
146  uint32 mem;
147 
148  for (mem = 0; mem < numBlocks; ++mem)
149  {
150  uint32 i;
151 
152  for (i = 0; i < memSize; ++i)
153  {
154  if ((i == eccInvPos0) || (i == eccInvPos1))
155  {
156  data |= (1 << bitPos);
157  }
158 
159  ++bitPos;
160 
161  if (bitPos >= 16)
162  {
163  mc->RDBFL[wordIx++].U = data;
164  bitPos = 0;
165  data = 0;
166  }
167  }
168  }
169 
170  /* final word? */
171  if (bitPos != 0)
172  {
173  mc->RDBFL[wordIx].U = data;
174  }
175  }
176 
177  /* start fill operation */
178  uint16 mcontrolMask = 0x4000; /* set USERED flag */
179  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DINIT_OFF) | (1 << IFX_MC_MCONTROL_START_OFF); /* START = DINIT = 1 */
180  mc->MCONTROL.U = mcontrolMask | (0 << IFX_MC_MCONTROL_DINIT_OFF) | (1 << IFX_MC_MCONTROL_DINIT_OFF); /* START = 0 */
181 }
182 
183 
185 {
186  volatile uint32 *mtuMemtest = (volatile uint32 *)((uint32)&MTU_MEMTEST0 + 4 * (mbistSel >> 5));
187  uint32 mask = 1 << (mbistSel & 0x1f);
188  *mtuMemtest &= ~mask;
189 }
190 
191 
193 {
194  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
195 
196  if (enable == FALSE)
197  {
198  mc->ECCS.U &= ~(1 << IFX_MC_ECCS_TRE_OFF);
199  }
200  else
201  {
202  mc->ECCS.U |= (1 << IFX_MC_ECCS_TRE_OFF);
203  }
204 }
205 
206 
208 {
209  volatile uint32 *mtuMemtest = (volatile uint32 *)((uint32)&MTU_MEMTEST0 + 4 * (mbistSel >> 5));
210  uint32 mask = 1 << (mbistSel & 0x1f);
211  *mtuMemtest |= mask;
212 }
213 
214 
215 uint32 IfxMtu_getSystemAddress(IfxMtu_MbistSel mbistSel, Ifx_MC_ETRR trackedSramAddress)
216 {
217  uint32 sramAddress = trackedSramAddress.B.ADDR;
218  uint32 mbi = trackedSramAddress.B.MBI;
219  uint32 systemAddress = 0;
220 
221  switch (mbistSel)
222  {
224  systemAddress = 0x70100000 | ((sramAddress << 3) | ((mbi & 1) << 2));
225  break;
226 
228  systemAddress = 0x70000000 | ((sramAddress << 4) | ((mbi & 3) << 2));
229  break;
230 
232  systemAddress = 0x60100000 | ((sramAddress << 4) | ((mbi & 1) << 3));
233  break;
234 
236  systemAddress = 0x60000000 | ((sramAddress << 5) | ((mbi & 3) << 2));
237  break;
238 
240  systemAddress = 0x60000000 | ((sramAddress << 5) | (1 << 4) | ((mbi & 3) << 2));
241  break;
242 
244  systemAddress = 0x50100000 | ((sramAddress << 4) | ((mbi & 1) << 3));
245  break;
246 
248  systemAddress = 0x50000000 | ((sramAddress << 5) | ((mbi & 3) << 2));
249  break;
250 
252  systemAddress = 0x50000000 | ((sramAddress << 5) | (1 << 4) | ((mbi & 3) << 2));
253  break;
254 
255  case IfxMtu_MbistSel_lmu:
256  systemAddress = 0xb0000000 | (sramAddress << 3);
257  break;
258 
259  case IfxMtu_MbistSel_dma:
260  systemAddress = 0xf0012000 | ((sramAddress << 5) | ((mbi & 3) << 3));
261  break;
262 
263  default:
264  systemAddress = 0; /* unsupported address descrambling */
265  }
266 
267  return systemAddress;
268 }
269 
270 
271 uint8 IfxMtu_getTrackedSramAddresses(IfxMtu_MbistSel mbistSel, Ifx_MC_ETRR *trackedSramAddresses)
272 {
273  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
274  uint8 validFlags = (mc->ECCD.U >> IFX_MC_ECCD_VAL_OFF) & IFX_MC_ECCD_VAL_MSK;
275  uint8 numTrackedAddresses = 0;
276  int i;
277 
278 #if IFX_MC_ECCD_VAL_LEN > IFXMTU_MAX_TRACKED_ADDRESSES
279 # error "Unexpected size of VAL mask"
280 #endif
281 
282  for (i = 0; i < IFXMTU_MAX_TRACKED_ADDRESSES; ++i)
283  {
284  if (validFlags & (1 << i))
285  {
286  trackedSramAddresses[numTrackedAddresses].U = mc->ETRR[i].U;
287  ++numTrackedAddresses;
288  }
289  }
290 
291  return numTrackedAddresses;
292 }
293 
294 
296 {
297  volatile uint32 *mtuMemstat = (volatile uint32 *)((uint32)&MTU_MEMSTAT0 + 4 * (mbistSel >> 5));
298  uint32 mask = 1 << (mbistSel & 0x1f);
299  return (*mtuMemstat & mask) != 0;
300 }
301 
302 
304 {
305  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
306  return mc->ECCS.B.TRE ? TRUE : FALSE;
307 }
308 
309 
311 {
312  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
313  return mc->ECCD.B.EOV ? TRUE : FALSE;
314 }
315 
316 
318 {
319  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
320  uint16 status;
321 
322  status = mc->MSTATUS.U;
323  return (boolean)(status & 0x01);
324 }
325 
326 
327 void IfxMtu_readSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
328 {
329  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
330 
331  /* configure MBIST for single read opeation */
332  uint16 mcontrolMask = 0x4000; /* set USERED flag */
333  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
334  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (1 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 read access */
335  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
336 
337  /* Set the address to be read (RAEN = 0) */
338  mc->RANGE.U = sramAddress;
339 
340  /* Start operation */
341  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
342  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
343 
344  /* wait for the end of the fill operation */
345  IfxMtu_waitForMbistDone(256, 1, mbistSel);
346 
347  while (!IfxMtu_isMbistDone(mbistSel))
348  {
349  __nop();
350  }
351 }
352 
353 
354 uint8 IfxMtu_runCheckerBoardTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr, uint32 numberRedundancyLines)
355 {
356  /* Select MBIST Memory Controller:
357  * Ifx_MC is a type describing structure of MBIST Memory Controller
358  * registers defined in IfxMc_regdef.h file - MC object */
359  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
360  uint32 configCheckerBoardSequence[4] = {
361  0x08001000, //up /lin/w0
362  0x08001001, //up /lin/r0
363  0x00011000, //down/lin/w1
364  0x00011001
365  }; //down/lin/r1
366  uint16 password = 0;
367  uint8 retVal = 0U;
368  uint8 testStep;
369  uint8 isEndInitEnabled = 0;
371 
372  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
374  {
375  /* Clear EndInit */
377  isEndInitEnabled = 1;
378  }
379 
380  /* Enable MBIST Memory Controller */
381  IfxMtu_enableMbistShell(mbistSel);
382 
383  /* for auto-init memories: wait for the end of the clear operation */
384  while (IfxMtu_isAutoInitRunning(mbistSel))
385  {}
386 
387  /* Set the range register */
388  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
389 
390  /* Run the test */
391  for (testStep = 0; testStep < 4; ++testStep)
392  {
393  mc->CONFIG0.U = configCheckerBoardSequence[testStep] & 0x0000FFFF;
394  mc->CONFIG1.U = (configCheckerBoardSequence[testStep] & 0xFFFF0000) >> 16;
395  mc->MCONTROL.U = numberRedundancyLines ? 0x30c9 : 0x00c9; // bit and row toggle
396  mc->MCONTROL.U = numberRedundancyLines ? 0x30c8 : 0x00c8; // MCONTROL.B.START will generate a RMW which is too long for small SRAMs!
397 
398  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
399  IfxScuWdt_setSafetyEndinit(password);
400 
401  /* wait for the end of the fill operation */
402  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
403  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
404 
405  while (!IfxMtu_isMbistDone(mbistSel))
406  {
407  __nop();
408  }
409 
410  /* Clear EndInit Again */
412 
413  /* Check the Fail Status */
414  if (mc->MSTATUS.B.FAIL)
415  {
416  /* Test has failed, check if any un-correctable error */
417  if (mc->ECCD.B.UERR)
418  {
419  /* Read Error tracking register and return saying test failed */
420  *errorAddr = mc->ETRR[0].U;
421  retVal = 1U;
422  break;
423  }
424  }
425  }
426 
427  /* Disable Memory Controller */
428 
429  IfxMtu_disableMbistShell(mbistSel);
430 
431  while (IfxMtu_isAutoInitRunning(mbistSel))
432  {}
433 
434  if (isEndInitEnabled == 1)
435  {
436  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
437  IfxScuWdt_setSafetyEndinit(password);
438  }
439 
440  return retVal;
441 }
442 
443 
444 uint8 IfxMtu_runMarchUTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr)
445 {
446  /* Select MBIST Memory Controller:
447  * Ifx_MC is a type describing structure of MBIST Memory Controller
448  * registers defined in IfxMc_regdef.h file - MC object */
449  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
450  uint32 configMarchUSequence[6] = {
451  0x08001000, //up /lin/w0
452  0x08064005, //up /lin/r0->w1->r1->w0
453  0x08022001, //up /lin/r0->w1
454  0x00094005, //down/lin/r1->w0->r0->w1
455  0x00012001, //down/lin/r1->w0
456  0x00001001
457  }; //down/lin/r0
458  uint16 password = 0;
459  uint8 retVal = 0U;
460  uint8 testStep;
461  uint8 isEndInitEnabled = 0;
463 
464  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
466  {
467  /* Clear EndInit */
469  isEndInitEnabled = 1;
470  }
471 
472  /* Enable MBIST Memory Controller */
473  IfxMtu_enableMbistShell(mbistSel);
474 
475  /* for auto-init memories: wait for the end of the clear operation */
476  while (IfxMtu_isAutoInitRunning(mbistSel))
477  {}
478 
479  /* Set the range register */
480  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
481 
482  /* Run the test */
483  for (testStep = 0; testStep < 6; ++testStep)
484  {
485  mc->CONFIG0.U = configMarchUSequence[testStep] & 0x0000FFFF;
486  mc->CONFIG1.U = (configMarchUSequence[testStep] & 0xFFFF0000) >> 16;
487  mc->MCONTROL.U = 0x0209;
488  mc->MCONTROL.B.START = 0;
489 
490  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
491  IfxScuWdt_setSafetyEndinit(password);
492 
493  /* wait for the end of the fill operation */
494  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
495  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
496 
497  while (!IfxMtu_isMbistDone(mbistSel))
498  {
499  __nop();
500  }
501 
502  /* Clear EndInit Again */
504 
505  /* Check the Fail Status */
506  if (mc->MSTATUS.B.FAIL)
507  {
508  /* Test has failed, check if any un-correctable error */
509  if (mc->ECCD.B.UERR)
510  {
511  /* Read Error tracking register and return saying test failed */
512  *errorAddr = mc->ETRR[0].U;
513  retVal = 1U;
514  break;
515  }
516  }
517  }
518 
519  /* Disable Memory Controller */
520  IfxMtu_disableMbistShell(mbistSel);
521 
522  /* for auto-init memories: wait for the end of the clear operation */
523  while (IfxMtu_isAutoInitRunning(mbistSel))
524  {}
525 
526  /* Restore the endinit state */
527  if (isEndInitEnabled == 1)
528  {
529  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
530  IfxScuWdt_setSafetyEndinit(password);
531  }
532 
533  return retVal;
534 }
535 
536 
537 uint8 IfxMtu_runNonDestructiveInversionTest(IfxMtu_MbistSel mbistSel, uint8 rangeSel, uint8 rangeAddrUp, uint8 rangeAddrLow, uint16 *errorAddr)
538 {
539  /* Select MBIST Memory Controller:
540  * Ifx_MC is a type describing structure of MBIST Memory Controller
541  * registers defined in IfxMc_regdef.h file - MC object */
542  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
543  uint16 password = 0;
544  uint8 retVal = 0U;
545  uint8 isEndInitEnabled = 0;
547 
548  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
550  {
551  /* Clear EndInit */
553  isEndInitEnabled = 1;
554  }
555 
556  /* Enable MBIST Memory Controller */
557  IfxMtu_enableMbistShell(mbistSel);
558 
559  /* for auto-init memories: wait for the end of the clear operation */
560  while (IfxMtu_isAutoInitRunning(mbistSel))
561  {}
562 
563  /* Configure Non-destructive Inversion test */
564  mc->CONFIG0.U = 0x4005; //NUMACCS=4, ACCSTYPE=5
565  mc->CONFIG1.U = 0x5000; //AG_MOD=5
566  /* Set the range register */
567  mc->RANGE.U = (rangeSel << 15) | (rangeAddrUp << 7) | (rangeAddrLow << 0);
568  /* Run the tests */
569  mc->MCONTROL.U = 0xF201;
570  mc->MCONTROL.B.START = 0;
571  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
572  IfxScuWdt_setSafetyEndinit(password);
573 
574  /* wait for the end of the fill operation */
575  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 4, mbistSel);
576  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
577 
578  while (!IfxMtu_isMbistDone(mbistSel))
579  {
580  __nop();
581  }
582 
583  /* Clear EndInit Again */
585 
586  /* Check the Fail Status */
587  if (mc->MSTATUS.B.FAIL)
588  {
589  /* Test has failed, check if any un-correctable error */
590  if (mc->ECCD.B.UERR)
591  {
592  /* Read the Error tracking register and return saying test failed */
593  *errorAddr = mc->ETRR[0].U;
594  retVal = 1U;
595  }
596  }
597 
598  /* Disable Memory Controller */
599  IfxMtu_disableMbistShell(mbistSel);
600 
601  /* for auto-init memories: wait for the end of the clear operation */
602  while (IfxMtu_isAutoInitRunning(mbistSel))
603  {}
604 
605  /* Restore the endinit state */
606  if (isEndInitEnabled == 1)
607  {
608  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
609  IfxScuWdt_setSafetyEndinit(password);
610  }
611 
612  return retVal;
613 }
614 
615 
616 static void IfxMtu_waitForMbistDone(uint32 towerDepth, uint8 numInstructions, IfxMtu_MbistSel mbistSel)
617 {
618  uint32 waitFact = (SCU_CCUCON0.B.SPBDIV / SCU_CCUCON0.B.SRIDIV) * numInstructions;
619  volatile uint32 waitTime;
620 
621  switch (mbistSel)
622  {
629  waitFact = waitFact * SCU_CCUCON1.B.GTMDIV;
630  break;
632  waitFact = waitFact * SCU_CCUCON1.B.GTMDIV;
633  break;
634 
638  waitFact = waitFact * SCU_CCUCON0.B.BAUD1DIV;
639 
640  break;
641 
644  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPll2ErayFrequency()) * numInstructions;
645  break;
646 
648  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPll2ErayFrequency()) * numInstructions * 4;
649  break;
650 
653  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPll2ErayFrequency()) * numInstructions;
654  break;
656  waitFact = (IfxScuCcu_getSriFrequency() / IfxScuCcu_getPll2ErayFrequency()) * numInstructions * 4;
657  break;
697  waitFact = waitFact * SCU_CCUCON2.B.BBBDIV;
698  break;
699  default:
700  break;
701  }
702 
703  if (numInstructions == 4)
704  {
705  waitTime = (towerDepth * waitFact) + 30;
706  }
707  else
708  {
709  waitTime = ((towerDepth / 4) * waitFact) + 30;
710  }
711 
712  waitTime = waitTime / 3;
713 
714  while (waitTime--)
715  {
716  __nop();
717  }
718 }
719 
720 
721 void IfxMtu_writeSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
722 {
723  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
724  uint8 isEndInitEnabled = 0;
725  uint16 password = 0;
727 
728  /* Check if the Endinit is cleared by application. If not, then handle it internally inside teh function.*/
730  {
731  /* Clear EndInit */
733  isEndInitEnabled = 1;
734  }
735 
736  /* configure MBIST for single write opeation */
737  uint16 mcontrolMask = 0x4000; /* set USERED flag */
738  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
739  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (0 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 write access */
740  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
741 
742  /* Set the address to be written (RAEN = 0) */
743  mc->RANGE.U = sramAddress;
744 
745  /* Start operation */
746  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
747  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
748 
749  if (isEndInitEnabled == 1)
750  {
751  /* Set EndInit Watchdog (to prevent Watchdog TO)*/
752  IfxScuWdt_setSafetyEndinit(password);
753  }
754 
755  /* Wait for the end of the operation */
756  IfxMtu_waitForMbistDone(IfxMtu_sramTable[mbistSel].mbistDelay, 1, mbistSel);
757  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, mc->MSTATUS.B.DONE != 0);
758 
759  while (!IfxMtu_isMbistDone(mbistSel))
760  {
761  __nop();
762  }
763 }