]> git.sur5r.net Git - freertos/blob
d0ff8a01d6ecc7489ee045a220ec0b7da274de40
[freertos] /
1 /***************************************************************************//**\r
2  * @file em_msc.h\r
3  * @brief Flash controller module (MSC) peripheral API\r
4  * @version 4.2.1\r
5  *******************************************************************************\r
6  * @section License\r
7  * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
8  *******************************************************************************\r
9  *\r
10  * Permission is granted to anyone to use this software for any purpose,\r
11  * including commercial applications, and to alter it and redistribute it\r
12  * freely, subject to the following restrictions:\r
13  *\r
14  * 1. The origin of this software must not be misrepresented; you must not\r
15  *    claim that you wrote the original software.\r
16  * 2. Altered source versions must be plainly marked as such, and must not be\r
17  *    misrepresented as being the original software.\r
18  * 3. This notice may not be removed or altered from any source distribution.\r
19  *\r
20  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
21  * obligation to support this Software. Silicon Labs is providing the\r
22  * Software "AS IS", with no express or implied warranties of any kind,\r
23  * including, but not limited to, any implied warranties of merchantability\r
24  * or fitness for any particular purpose or warranties against infringement\r
25  * of any proprietary rights of a third party.\r
26  *\r
27  * Silicon Labs will not be liable for any consequential, incidental, or\r
28  * special damages, or any other relief, or for any claim by any third party,\r
29  * arising from your use of this Software.\r
30  *\r
31  ******************************************************************************/\r
32 \r
33 #ifndef __SILICON_LABS_EM_MSC_H__\r
34 #define __SILICON_LABS_EM_MSC_H__\r
35 \r
36 #include "em_device.h"\r
37 #if defined(MSC_COUNT) && (MSC_COUNT > 0)\r
38 \r
39 #include <stdint.h>\r
40 #include <stdbool.h>\r
41 #include "em_bus.h"\r
42 \r
43 #ifdef __cplusplus\r
44 extern "C" {\r
45 #endif\r
46 \r
47 /***************************************************************************//**\r
48  * @addtogroup EM_Library\r
49  * @{\r
50  ******************************************************************************/\r
51 \r
52 /***************************************************************************//**\r
53  * @addtogroup MSC\r
54  * @brief Flash controller (MSC) peripheral API\r
55  * @{\r
56  ******************************************************************************/\r
57 \r
58 /*******************************************************************************\r
59  *************************   DEFINES   *****************************************\r
60  ******************************************************************************/\r
61 \r
62 /**\r
63  * @brief\r
64  *    The timeout used while waiting for the flash to become ready after\r
65  *    a write. This number indicates the number of iterations to perform before\r
66  *    issuing a timeout.\r
67  * @note\r
68  *    This timeout is set very large (in the order of 100x longer than\r
69  *    necessary). This is to avoid any corner cases.\r
70  *\r
71  */\r
72 #define MSC_PROGRAM_TIMEOUT    10000000ul\r
73 \r
74 /**\r
75  * @brief\r
76  *    By compiling with the define EM_MSC_RUN_FROM_FLASH the Flash\r
77  *    controller (MSC) peripheral will remain in and execute from flash.\r
78  *    This is useful for targets that don't want to allocate RAM space to\r
79  *    hold the flash functions.  Without this define the MSC peripheral\r
80  *    functions will be copied into and run out of RAM.\r
81  * @note\r
82  *    This define is commented out by default so the MSC controller API\r
83  *    will run from RAM by default.\r
84  *\r
85  */\r
86 #if defined( DOXY_DOC_ONLY )\r
87 #define EM_MSC_RUN_FROM_FLASH\r
88 #else\r
89 //#define EM_MSC_RUN_FROM_FLASH\r
90 #endif\r
91 \r
92 /*******************************************************************************\r
93  *************************   TYPEDEFS   ****************************************\r
94  ******************************************************************************/\r
95 \r
96 /** Return codes for writing/erasing the flash */\r
97 typedef enum\r
98 {\r
99   mscReturnOk          = 0,  /**< Flash write/erase successful. */\r
100   mscReturnInvalidAddr = -1, /**< Invalid address. Write to an address that is not flash. */\r
101   mscReturnLocked      = -2, /**< Flash address is locked. */\r
102   mscReturnTimeOut     = -3, /**< Timeout while writing to flash. */\r
103   mscReturnUnaligned   = -4  /**< Unaligned access to flash. */\r
104 } MSC_Status_TypeDef;\r
105 \r
106 \r
107 #if defined( _MSC_READCTRL_BUSSTRATEGY_MASK )\r
108 /** Strategy for prioritized bus access */\r
109 typedef enum\r
110 {\r
111   mscBusStrategyCPU = MSC_READCTRL_BUSSTRATEGY_CPU,       /**< Prioritize CPU bus accesses */\r
112   mscBusStrategyDMA = MSC_READCTRL_BUSSTRATEGY_DMA,       /**< Prioritize DMA bus accesses */\r
113   mscBusStrategyDMAEM1 = MSC_READCTRL_BUSSTRATEGY_DMAEM1, /**< Prioritize DMAEM1 for bus accesses */\r
114   mscBusStrategyNone = MSC_READCTRL_BUSSTRATEGY_NONE      /**< No unit has bus priority */\r
115 } MSC_BusStrategy_Typedef;\r
116 #endif\r
117 \r
118 /** Code execution configuration */\r
119 typedef struct\r
120 {\r
121   bool scbtEn;          /**< Enable Suppressed Conditional Branch Target Prefetch */\r
122   bool prefetchEn;      /**< Enable MSC prefetching */\r
123   bool ifcDis;          /**< Disable instruction cache */\r
124   bool aiDis;           /**< Disable automatic cache invalidation on write or erase */\r
125   bool iccDis;          /**< Disable automatic caching of fetches in interrupt context */\r
126   bool useHprot;        /**< Use ahb_hprot to determine if the instruction is cacheable or not */\r
127 } MSC_ExecConfig_TypeDef;\r
128 \r
129 /** Default MSC ExecConfig initialization */\r
130 #define MSC_EXECCONFIG_DEFAULT  \\r
131 {                               \\r
132   false,                        \\r
133   true,                         \\r
134   false,                        \\r
135   false,                        \\r
136   false,                        \\r
137   false,                        \\r
138 }\r
139 \r
140 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
141 /* Legacy type names */\r
142 #define mscBusStrategy_Typedef MSC_BusStrategy_Typedef\r
143 #define msc_Return_TypeDef MSC_Status_TypeDef\r
144 /** @endcond */\r
145 \r
146 /*******************************************************************************\r
147  *************************   PROTOTYPES   **************************************\r
148  ******************************************************************************/\r
149 \r
150 void MSC_Init(void);\r
151 void MSC_Deinit(void);\r
152 #if !defined( _EFM32_GECKO_FAMILY )\r
153 void MSC_ExecConfigSet(MSC_ExecConfig_TypeDef *execConfig);\r
154 #endif\r
155 \r
156 /***************************************************************************//**\r
157  * @brief\r
158  *    Clear one or more pending MSC interrupts.\r
159  *\r
160  * @param[in] flags\r
161  *    Pending MSC intterupt source to clear. Use a bitwise logic OR combination\r
162  *   of valid interrupt flags for the MSC module (MSC_IF_nnn).\r
163  ******************************************************************************/\r
164 __STATIC_INLINE void MSC_IntClear(uint32_t flags)\r
165 {\r
166   MSC->IFC = flags;\r
167 }\r
168 \r
169 /***************************************************************************//**\r
170  * @brief\r
171  *   Disable one or more MSC interrupts.\r
172  *\r
173  * @param[in] flags\r
174  *   MSC interrupt sources to disable. Use a bitwise logic OR combination of\r
175  *   valid interrupt flags for the MSC module (MSC_IF_nnn).\r
176  ******************************************************************************/\r
177 __STATIC_INLINE void MSC_IntDisable(uint32_t flags)\r
178 {\r
179   MSC->IEN &= ~(flags);\r
180 }\r
181 \r
182 \r
183 /***************************************************************************//**\r
184  * @brief\r
185  *   Enable one or more MSC interrupts.\r
186  *\r
187  * @note\r
188  *   Depending on the use, a pending interrupt may already be set prior to\r
189  *   enabling the interrupt. Consider using MSC_IntClear() prior to enabling\r
190  *   if such a pending interrupt should be ignored.\r
191  *\r
192  * @param[in] flags\r
193  *   MSC interrupt sources to enable. Use a bitwise logic OR combination of\r
194  *   valid interrupt flags for the MSC module (MSC_IF_nnn).\r
195  ******************************************************************************/\r
196 __STATIC_INLINE void MSC_IntEnable(uint32_t flags)\r
197 {\r
198   MSC->IEN |= flags;\r
199 }\r
200 \r
201 \r
202 /***************************************************************************//**\r
203  * @brief\r
204  *   Get pending MSC interrupt flags.\r
205  *\r
206  * @note\r
207  *   The event bits are not cleared by the use of this function.\r
208  *\r
209  * @return\r
210  *   MSC interrupt sources pending. A bitwise logic OR combination of valid\r
211  *   interrupt flags for the MSC module (MSC_IF_nnn).\r
212  ******************************************************************************/\r
213 __STATIC_INLINE uint32_t MSC_IntGet(void)\r
214 {\r
215   return(MSC->IF);\r
216 }\r
217 \r
218 \r
219 /***************************************************************************//**\r
220  * @brief\r
221  *   Get enabled and pending MSC interrupt flags.\r
222  *   Useful for handling more interrupt sources in the same interrupt handler.\r
223  *\r
224  * @note\r
225  *   Interrupt flags are not cleared by the use of this function.\r
226  *\r
227  * @return\r
228  *   Pending and enabled MSC interrupt sources\r
229  *   The return value is the bitwise AND of\r
230  *   - the enabled interrupt sources in MSC_IEN and\r
231  *   - the pending interrupt flags MSC_IF\r
232  ******************************************************************************/\r
233 __STATIC_INLINE uint32_t MSC_IntGetEnabled(void)\r
234 {\r
235   uint32_t ien;\r
236 \r
237   ien = MSC->IEN;\r
238   return MSC->IF & ien;\r
239 }\r
240 \r
241 \r
242 /***************************************************************************//**\r
243  * @brief\r
244  *   Set one or more pending MSC interrupts from SW.\r
245  *\r
246  * @param[in] flags\r
247  *   MSC interrupt sources to set to pending. Use a bitwise logic OR combination of\r
248  *   valid interrupt flags for the MSC module (MSC_IF_nnn).\r
249  ******************************************************************************/\r
250 __STATIC_INLINE void MSC_IntSet(uint32_t flags)\r
251 {\r
252   MSC->IFS = flags;\r
253 }\r
254 \r
255 \r
256 #if defined( MSC_IF_CHOF ) && defined( MSC_IF_CMOF )\r
257 /***************************************************************************//**\r
258  * @brief\r
259  *   Starts measuring cache hit ratio.\r
260  * @details\r
261  *   This function starts the performance counters. It is defined inline to\r
262  *   minimize the impact of this code on the measurement itself.\r
263  ******************************************************************************/\r
264 __STATIC_INLINE void MSC_StartCacheMeasurement(void)\r
265 {\r
266   /* Clear CMOF and CHOF to catch these later */\r
267   MSC->IFC = MSC_IF_CHOF | MSC_IF_CMOF;\r
268 \r
269   /* Start performance counters */\r
270 #if defined( _MSC_CACHECMD_MASK )\r
271   MSC->CACHECMD = MSC_CACHECMD_STARTPC;\r
272 #else\r
273   MSC->CMD = MSC_CMD_STARTPC;\r
274 #endif\r
275 }\r
276 \r
277 \r
278 /***************************************************************************//**\r
279  * @brief\r
280  *   Stops measuring the hit rate.\r
281  * @note\r
282  *   This function is defined inline to minimize the impact of this\r
283  *   code on the measurement itself.\r
284  *   This code only works for relatively short sections of code. If you wish\r
285  *   to measure longer sections of code you need to implement a IRQ Handler for\r
286  *   The CHOF and CMOF overflow interrupts. Theses overflows needs to be\r
287  *   counted and included in the total.\r
288  *   The functions can then be implemented as follows:\r
289  * @verbatim\r
290  * volatile uint32_t hitOverflows\r
291  * volatile uint32_t missOverflows\r
292  *\r
293  * void MSC_IRQHandler(void)\r
294  * {\r
295  *   uint32_t flags;\r
296  *   flags = MSC->IF;\r
297  *   if (flags & MSC_IF_CHOF)\r
298  *   {\r
299  *      MSC->IFC = MSC_IF_CHOF;\r
300  *      hitOverflows++;\r
301  *   }\r
302  *   if (flags & MSC_IF_CMOF)\r
303  *   {\r
304  *     MSC->IFC = MSC_IF_CMOF;\r
305  *     missOverflows++;\r
306  *   }\r
307  * }\r
308  *\r
309  * void startPerformanceCounters(void)\r
310  * {\r
311  *   hitOverflows = 0;\r
312  *   missOverflows = 0;\r
313  *\r
314  *   MSC_IntEnable(MSC_IF_CHOF | MSC_IF_CMOF);\r
315  *   NVIC_EnableIRQ(MSC_IRQn);\r
316  *\r
317  *   MSC_StartCacheMeasurement();\r
318  * }\r
319  * @endverbatim\r
320  * @return\r
321  *   Returns -1 if there has been no cache accesses.\r
322  *   Returns -2 if there has been an overflow in the performance counters.\r
323  *   If not, it will return the percentage of hits versus misses.\r
324  ******************************************************************************/\r
325 __STATIC_INLINE int32_t MSC_GetCacheMeasurement(void)\r
326 {\r
327   int32_t total;\r
328   /* Stop the counter before computing the hit-rate */\r
329 #if defined( _MSC_CACHECMD_MASK )\r
330   MSC->CACHECMD = MSC_CACHECMD_STOPPC;\r
331 #else\r
332   MSC->CMD = MSC_CMD_STOPPC;\r
333 #endif\r
334 \r
335   /* Check for overflows in performance counters */\r
336   if (MSC->IF & (MSC_IF_CHOF | MSC_IF_CMOF))\r
337     return -2;\r
338 \r
339   /* Because the hits and misses are volatile, we need to split this up into\r
340    * two statements to avoid a compiler warning regarding the order of volatile\r
341    * accesses. */\r
342   total  = MSC->CACHEHITS;\r
343   total += MSC->CACHEMISSES;\r
344 \r
345   /* To avoid a division by zero. */\r
346   if (total == 0)\r
347     return -1;\r
348 \r
349   return (MSC->CACHEHITS * 100) / total;\r
350 }\r
351 \r
352 \r
353 /***************************************************************************//**\r
354  * @brief\r
355  *   Flush the contents of the instruction cache.\r
356  ******************************************************************************/\r
357 __STATIC_INLINE void MSC_FlushCache(void)\r
358 {\r
359 #if defined( _MSC_CACHECMD_MASK )\r
360   MSC->CACHECMD = MSC_CACHECMD_INVCACHE;\r
361 #else\r
362   MSC->CMD = MSC_CMD_INVCACHE;\r
363 #endif\r
364 }\r
365 \r
366 \r
367 /***************************************************************************//**\r
368  * @brief\r
369  *   Enable or disable instruction cache functionality\r
370  * @param[in] enable\r
371  *   Enable instruction cache. Default is on.\r
372  ******************************************************************************/\r
373 __STATIC_INLINE void MSC_EnableCache(bool enable)\r
374 {\r
375   BUS_RegBitWrite(&(MSC->READCTRL), _MSC_READCTRL_IFCDIS_SHIFT, !enable);\r
376 }\r
377 \r
378 \r
379 #if defined( MSC_READCTRL_ICCDIS )\r
380 /***************************************************************************//**\r
381  * @brief\r
382  *   Enable or disable instruction cache functionality in IRQs\r
383  * @param[in] enable\r
384  *   Enable instruction cache. Default is on.\r
385  ******************************************************************************/\r
386 __STATIC_INLINE void MSC_EnableCacheIRQs(bool enable)\r
387 {\r
388   BUS_RegBitWrite(&(MSC->READCTRL), _MSC_READCTRL_ICCDIS_SHIFT, !enable);\r
389 }\r
390 #endif\r
391 \r
392 \r
393 /***************************************************************************//**\r
394  * @brief\r
395  *   Enable or disable instruction cache flushing when writing to flash\r
396  * @param[in] enable\r
397  *   Enable automatic cache flushing. Default is on.\r
398  ******************************************************************************/\r
399 __STATIC_INLINE void MSC_EnableAutoCacheFlush(bool enable)\r
400 {\r
401   BUS_RegBitWrite(&(MSC->READCTRL), _MSC_READCTRL_AIDIS_SHIFT, !enable);\r
402 }\r
403 #endif /* defined( MSC_IF_CHOF ) && defined( MSC_IF_CMOF ) */\r
404 \r
405 \r
406 #if defined( _MSC_READCTRL_BUSSTRATEGY_MASK )\r
407 /***************************************************************************//**\r
408  * @brief\r
409  *   Configure which unit should get priority on system bus.\r
410  * @param[in] mode\r
411  *   Unit to prioritize bus accesses for.\r
412  ******************************************************************************/\r
413 __STATIC_INLINE void MSC_BusStrategy(mscBusStrategy_Typedef mode)\r
414 {\r
415   MSC->READCTRL = (MSC->READCTRL & ~(_MSC_READCTRL_BUSSTRATEGY_MASK)) | mode;\r
416 }\r
417 #endif\r
418 \r
419 #if defined(EM_MSC_RUN_FROM_FLASH)\r
420 #define MSC_FUNC_PREFIX\r
421 #define MSC_FUNC_POSTFIX\r
422 #elif defined(__CC_ARM)\r
423 #define MSC_FUNC_PREFIX\r
424 #define MSC_FUNC_POSTFIX\r
425 #elif defined(__ICCARM__)\r
426 #define MSC_FUNC_PREFIX   __ramfunc\r
427 #define MSC_FUNC_POSTFIX\r
428 #elif defined(__GNUC__) && defined(__CROSSWORKS_ARM)\r
429 #define MSC_FUNC_PREFIX\r
430 #define MSC_FUNC_POSTFIX  __attribute__ ((section(".fast")))\r
431 #elif defined(__GNUC__)\r
432 #define MSC_FUNC_PREFIX\r
433 #define MSC_FUNC_POSTFIX  __attribute__ ((section(".ram")))\r
434 #endif\r
435 \r
436 \r
437 MSC_FUNC_PREFIX MSC_Status_TypeDef\r
438   MSC_WriteWord(uint32_t *address,\r
439                 void const *data,\r
440                 uint32_t numBytes) MSC_FUNC_POSTFIX;\r
441 \r
442 #if !defined( _EFM32_GECKO_FAMILY )\r
443 MSC_FUNC_PREFIX MSC_Status_TypeDef\r
444   MSC_WriteWordFast(uint32_t *address,\r
445                     void const *data,\r
446                     uint32_t numBytes) MSC_FUNC_POSTFIX;\r
447 \r
448 #endif\r
449 \r
450 MSC_FUNC_PREFIX MSC_Status_TypeDef\r
451   MSC_ErasePage(uint32_t *startAddress) MSC_FUNC_POSTFIX;\r
452 \r
453 #if defined( _MSC_MASSLOCK_MASK )\r
454 MSC_FUNC_PREFIX MSC_Status_TypeDef MSC_MassErase(void) MSC_FUNC_POSTFIX;\r
455 #endif\r
456 \r
457 /** @} (end addtogroup MSC) */\r
458 /** @} (end addtogroup EM_Library) */\r
459 \r
460 #ifdef __cplusplus\r
461 }\r
462 #endif\r
463 \r
464 #endif /* defined(MSC_COUNT) && (MSC_COUNT > 0) */\r
465 #endif /* __SILICON_LABS_EM_MSC_H__ */\r