iLLD_TC27xC  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_0_1_0_10
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 #include "_Reg/IfxMc_bf.h"
32 #include "_Utilities/Ifx_Assert.h"
33 
34 /******************************************************************************/
35 /*-------------------------Function Implementations---------------------------*/
36 /******************************************************************************/
37 
39 {
40  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
41  mc->ECCD.U |= (1 << IFX_MC_ECCD_TRC_OFF);
42 }
43 
44 
46 {
47  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
48 
49  IfxMtu_enableMbistShell(mbistSel);
50 
51  /* for auto-init memories: wait for the end of the clear operation */
52  while (IfxMtu_isAutoInitRunning(mbistSel))
53  {}
54 
55  /* write valid ECC code for all-zero data into RDBFL registers */
56  {
58  const IfxMtu_SramItem *item = (IfxMtu_SramItem *)&IfxMtu_sramTable[mbistSel];
59 
60  uint8 numBlocks = item->numBlocks;
61  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, numBlocks > 0);
62 
63  uint8 dataSize = item->dataSize;
64  uint8 eccSize = item->eccSize;
65  uint32 eccInvPos0 = dataSize + item->eccInvPos0;
66  uint32 eccInvPos1 = dataSize + item->eccInvPos1;
67 
68  uint32 memSize = dataSize + eccSize;
69 
70  uint32 bitPos = 0;
71  uint32 wordIx = 0;
72  uint32 data = 0;
73 
74  /* de-serialize data stream into 16bit packets */
75  uint32 mem;
76 
77  for (mem = 0; mem < numBlocks; ++mem)
78  {
79  uint32 i;
80 
81  for (i = 0; i < memSize; ++i)
82  {
83  if ((i == eccInvPos0) || (i == eccInvPos1))
84  {
85  data |= (1 << bitPos);
86  }
87 
88  ++bitPos;
89 
90  if (bitPos >= 16)
91  {
92  mc->RDBFL[wordIx++].U = data;
93  bitPos = 0;
94  data = 0;
95  }
96  }
97  }
98 
99  /* final word? */
100  if (bitPos != 0)
101  {
102  mc->RDBFL[wordIx++].U = data;
103  bitPos = 0;
104  data = 0;
105  }
106  }
107 
108  /* start fill operation */
109  uint16 mcontrolMask = 0x4000; /* set USERED flag */
110  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DINIT_OFF) | (1 << IFX_MC_MCONTROL_START_OFF); /* START = DINIT = 1 */
111  mc->MCONTROL.U = mcontrolMask | (0 << IFX_MC_MCONTROL_DINIT_OFF) | (1 << IFX_MC_MCONTROL_DINIT_OFF); /* START = 0 */
112 
113  /* wait for the end of the fill operation */
114  while (!mc->MSTATUS.B.DONE)
115  {}
116 
117  /* Before clearing the ECC error flags we've to issue a dummy SRAM access to get a valid memory output */
118  IfxMtu_readSramAddress(mbistSel, 0x0000);
119 
120  /* Note: a SMU alarm will be flagged HERE if the wrong ECC has been written! */
121 
122  IfxMtu_disableMbistShell(mbistSel);
123 }
124 
125 
127 {
128  volatile uint32 *mtuMemtest = (volatile uint32 *)((uint32)&MTU_MEMTEST0 + 4 * (mbistSel >> 5));
129  uint32 mask = 1 << (mbistSel & 0x1f);
130  *mtuMemtest &= ~mask;
131 }
132 
133 
135 {
136  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
137 
138  if (enable == FALSE)
139  {
140  mc->ECCS.U &= ~(1 << IFX_MC_ECCS_TRE_OFF);
141  }
142  else
143  {
144  mc->ECCS.U |= (1 << IFX_MC_ECCS_TRE_OFF);
145  }
146 }
147 
148 
150 {
151  volatile uint32 *mtuMemtest = (volatile uint32 *)((uint32)&MTU_MEMTEST0 + 4 * (mbistSel >> 5));
152  uint32 mask = 1 << (mbistSel & 0x1f);
153  *mtuMemtest |= mask;
154 }
155 
156 
157 uint32 IfxMtu_getSystemAddress(IfxMtu_MbistSel mbistSel, Ifx_MC_ETRR trackedSramAddress)
158 {
159  uint32 sramAddress = trackedSramAddress.B.ADDR;
160  uint32 mbi = trackedSramAddress.B.MBI;
161  uint32 systemAddress = 0;
162 
163  switch (mbistSel)
164  {
166  systemAddress = 0x70100000 | ((sramAddress << 3) | ((mbi & 1) << 2));
167  break;
168 
170  systemAddress = 0x70000000 | ((sramAddress << 4) | ((mbi & 3) << 2));
171  break;
172 
174  systemAddress = 0x60100000 | ((sramAddress << 4) | ((mbi & 1) << 3));
175  break;
176 
178  systemAddress = 0x60000000 | ((sramAddress << 4) | ((mbi & 3) << 2));
179  break;
180 
182  systemAddress = 0x50100000 | ((sramAddress << 4) | ((mbi & 1) << 3));
183  break;
184 
186  systemAddress = 0x50000000 | ((sramAddress << 4) | ((mbi & 3) << 2));
187  break;
188 
189  case IfxMtu_MbistSel_lmu:
190  systemAddress = 0xb0000000 | (sramAddress << 3);
191  break;
192 
193  case IfxMtu_MbistSel_dma:
194  systemAddress = 0xf0012000 | ((sramAddress << 5) | ((mbi & 3) << 3));
195  break;
196 
197  default:
198  systemAddress = 0; /* unsupported address descrambling */
199  }
200 
201  return systemAddress;
202 }
203 
204 
205 uint8 IfxMtu_getTrackedSramAddresses(IfxMtu_MbistSel mbistSel, Ifx_MC_ETRR *trackedSramAddresses)
206 {
207  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
208  uint8 validFlags = (mc->ECCD.U >> IFX_MC_ECCD_VAL_OFF) & IFX_MC_ECCD_VAL_MSK;
209  uint8 numTrackedAddresses = 0;
210  int i;
211 
212 #if IFX_MC_ECCD_VAL_LEN > IFXMTU_MAX_TRACKED_ADDRESSES
213 # error "Unexpected size of VAL mask"
214 #endif
215 
216  for (i = 0; i < IFXMTU_MAX_TRACKED_ADDRESSES; ++i)
217  {
218  if (validFlags & (1 << i))
219  {
220  trackedSramAddresses[numTrackedAddresses].U = mc->ETRR[i].U;
221  ++numTrackedAddresses;
222  }
223  }
224 
225  return numTrackedAddresses;
226 }
227 
228 
230 {
231  volatile uint32 *mtuMemstat = (volatile uint32 *)((uint32)&MTU_MEMSTAT0 + 4 * (mbistSel >> 5));
232  uint32 mask = 1 << (mbistSel & 0x1f);
233  return (*mtuMemstat & mask) != 0;
234 }
235 
236 
238 {
239  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
240  return mc->ECCS.B.TRE ? TRUE : FALSE;
241 }
242 
243 
245 {
246  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
247  return mc->ECCD.B.EOV ? TRUE : FALSE;
248 }
249 
250 
251 void IfxMtu_readSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
252 {
253  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
254 
255  /* configure MBIST for single read opeation */
256  uint16 mcontrolMask = 0x4000; /* set USERED flag */
257  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
258  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (1 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 read access */
259  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
260 
261  /* Set the address to be read (RAEN = 0) */
262  mc->RANGE.U = sramAddress;
263 
264  /* Start operation */
265  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
266  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
267 
268  /* Wait for the end of the operation */
269  while (!mc->MSTATUS.B.DONE)
270  {}
271 }
272 
273 
274 void IfxMtu_writeSramAddress(IfxMtu_MbistSel mbistSel, uint16 sramAddress)
275 {
276  Ifx_MC *mc = (Ifx_MC *)(IFXMTU_MC_ADDRESS_BASE + 0x100 * mbistSel);
277 
278  /* configure MBIST for single write opeation */
279  uint16 mcontrolMask = 0x4000; /* set USERED flag */
280  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
281  mc->CONFIG0.U = (1 << IFX_MC_CONFIG0_NUMACCS_OFF) | (0 << IFX_MC_CONFIG0_ACCSTYPE_OFF); /* 1 write access */
282  mc->CONFIG1.U = 0; /* ensure that linear scrambling is used */
283 
284  /* Set the address to be written (RAEN = 0) */
285  mc->RANGE.U = sramAddress;
286 
287  /* Start operation */
288  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF) | (1 << IFX_MC_MCONTROL_START_OFF);
289  mc->MCONTROL.U = mcontrolMask | (1 << IFX_MC_MCONTROL_DIR_OFF);
290 
291  /* Wait for the end of the operation */
292  while (!mc->MSTATUS.B.DONE)
293  {}
294 }