]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/PIC32MX_MPLAB/ConfigPerformance.c
4b38fc062cede9261b8624b6e8c31811dcf15af1
[freertos] / FreeRTOS / Demo / PIC32MX_MPLAB / ConfigPerformance.c
1 /*\r
2     FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd. \r
3     All rights reserved\r
4 \r
5     VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS provides completely free yet professionally developed,    *\r
10      *    robust, strictly quality controlled, supported, and cross          *\r
11      *    platform software that has become a de facto standard.             *\r
12      *                                                                       *\r
13      *    Help yourself get started quickly and support the FreeRTOS         *\r
14      *    project by purchasing a FreeRTOS tutorial book, reference          *\r
15      *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
16      *                                                                       *\r
17      *    Thank you!                                                         *\r
18      *                                                                       *\r
19     ***************************************************************************\r
20 \r
21     This file is part of the FreeRTOS distribution.\r
22 \r
23     FreeRTOS is free software; you can redistribute it and/or modify it under\r
24     the terms of the GNU General Public License (version 2) as published by the\r
25     Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.\r
26 \r
27     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
28     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
29     >>!   obliged to provide the source code for proprietary components     !<<\r
30     >>!   outside of the FreeRTOS kernel.                                   !<<\r
31 \r
32     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
33     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
34     FOR A PARTICULAR PURPOSE.  Full license text is available from the following\r
35     link: http://www.freertos.org/a00114.html\r
36 \r
37     1 tab == 4 spaces!\r
38 \r
39     ***************************************************************************\r
40      *                                                                       *\r
41      *    Having a problem?  Start by reading the FAQ "My application does   *\r
42      *    not run, what could be wrong?"                                     *\r
43      *                                                                       *\r
44      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
45      *                                                                       *\r
46     ***************************************************************************\r
47 \r
48     http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
49     license and Real Time Engineers Ltd. contact details.\r
50 \r
51     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
52     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
53     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
54 \r
55     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
56     Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
57     licenses offer ticketed support, indemnification and middleware.\r
58 \r
59     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
60     engineered and independently SIL3 certified version for use in safety and\r
61     mission critical applications that require provable dependability.\r
62 \r
63     1 tab == 4 spaces!\r
64 */\r
65 \r
66 /*\r
67  * This file implements functions to access and manipulate the PIC32 hardware\r
68  * without reliance on third party library functions that may be liable to\r
69  * change.\r
70  */\r
71 \r
72 /* FreeRTOS includes. */\r
73 #include "FreeRTOS.h"\r
74 \r
75 /* Demo includes. */\r
76 #include "ConfigPerformance.h"\r
77 \r
78 /* Hardware specific definitions. */\r
79 #define hwCHECON_PREFEN_BITS                    ( 0x03UL << 0x04UL )\r
80 #define hwCHECON_WAIT_STAT_BITS                 ( 0x07UL << 0UL )\r
81 #define hwMAX_FLASH_SPEED                               ( 30000000UL )\r
82 #define hwPERIPHERAL_CLOCK_DIV_BY_2             ( 1UL << 0x13UL )\r
83 #define hwUNLOCK_KEY_0                                  ( 0xAA996655UL )\r
84 #define hwUNLOCK_KEY_1                                  ( 0x556699AAUL )\r
85 #define hwLOCK_KEY                                              ( 0x33333333UL )\r
86 #define hwGLOBAL_INTERRUPT_BIT                  ( 0x01UL )\r
87 #define hwBEV_BIT                                               ( 0x00400000 )\r
88 #define hwEXL_BIT                                               ( 0x00000002 )\r
89 #define hwIV_BIT                                                ( 0x00800000 )\r
90 \r
91 /*\r
92  * Set the flash wait states for the configured CPU clock speed.\r
93  */\r
94 static void prvConfigureWaitStates( void );\r
95 \r
96 /*\r
97  * Use a divisor of 2 on the peripheral bus.\r
98  */\r
99 static void prvConfigurePeripheralBus( void );\r
100 \r
101 /*\r
102  * Enable the cache.\r
103  */\r
104 static void __attribute__ ((nomips16)) prvKSeg0CacheOn( void );\r
105 \r
106 /*-----------------------------------------------------------*/\r
107 \r
108 void vHardwareConfigurePerformance( void )\r
109 {\r
110 unsigned long ulStatus;\r
111 #ifdef _PCACHE\r
112         unsigned long ulCacheStatus;\r
113 #endif\r
114 \r
115         /* Disable interrupts - note taskDISABLE_INTERRUPTS() cannot be used here as\r
116         FreeRTOS does not globally disable interrupt. */\r
117         ulStatus = _CP0_GET_STATUS();\r
118         _CP0_SET_STATUS( ulStatus & ~hwGLOBAL_INTERRUPT_BIT );\r
119 \r
120         prvConfigurePeripheralBus();\r
121         prvConfigureWaitStates();\r
122 \r
123         /* Disable DRM wait state. */\r
124         BMXCONCLR = _BMXCON_BMXWSDRM_MASK;\r
125 \r
126         #ifdef _PCACHE\r
127         {\r
128                 /* Read the current CHECON value. */\r
129                 ulCacheStatus = CHECON;\r
130 \r
131                 /* All the PREFEN bits are being set, so no need to clear first. */\r
132                 ulCacheStatus |= hwCHECON_PREFEN_BITS;\r
133 \r
134                 /* Write back the new value. */\r
135                 CHECON = ulCacheStatus;\r
136                 prvKSeg0CacheOn();\r
137         }\r
138         #endif\r
139 \r
140         /* Reset the status register back to its original value so the original\r
141         interrupt enable status is retored. */\r
142         _CP0_SET_STATUS( ulStatus );\r
143 }\r
144 /*-----------------------------------------------------------*/\r
145 \r
146 void vHardwareUseMultiVectoredInterrupts( void )\r
147 {\r
148 unsigned long ulStatus, ulCause;\r
149 extern unsigned long _ebase_address[];\r
150 \r
151         /* Get current status. */\r
152         ulStatus = _CP0_GET_STATUS();\r
153 \r
154         /* Disable interrupts. */\r
155         ulStatus &= ~hwGLOBAL_INTERRUPT_BIT;\r
156 \r
157         /* Set BEV bit. */\r
158         ulStatus |= hwBEV_BIT;\r
159 \r
160         /* Write status back. */\r
161         _CP0_SET_STATUS( ulStatus );\r
162 \r
163         /* Setup EBase. */\r
164         _CP0_SET_EBASE( ( unsigned long ) _ebase_address );\r
165         \r
166         /* Space vectors by 0x20 bytes. */\r
167         _CP0_XCH_INTCTL( 0x20 );\r
168 \r
169         /* Set the IV bit in the CAUSE register. */\r
170         ulCause = _CP0_GET_CAUSE();\r
171         ulCause |= hwIV_BIT;\r
172         _CP0_SET_CAUSE( ulCause );\r
173 \r
174         /* Clear BEV and EXL bits in status. */\r
175         ulStatus &= ~( hwBEV_BIT | hwEXL_BIT );\r
176         _CP0_SET_STATUS( ulStatus );\r
177 \r
178         /* Set MVEC bit. */\r
179         INTCONbits.MVEC = 1;\r
180         \r
181         /* Finally enable interrupts again. */\r
182         ulStatus |= hwGLOBAL_INTERRUPT_BIT;\r
183         _CP0_SET_STATUS( ulStatus );\r
184 }\r
185 /*-----------------------------------------------------------*/\r
186 \r
187 static void prvConfigurePeripheralBus( void )\r
188 {\r
189 unsigned long ulDMAStatus;\r
190 __OSCCONbits_t xOSCCONBits;\r
191 \r
192         /* Unlock after suspending. */\r
193         ulDMAStatus = DMACONbits.SUSPEND;\r
194         if( ulDMAStatus == 0 )\r
195         {\r
196                 DMACONSET = _DMACON_SUSPEND_MASK;\r
197 \r
198                 /* Wait until actually suspended. */\r
199                 while( DMACONbits.SUSPEND == 0 );\r
200         }\r
201 \r
202         SYSKEY = 0;\r
203         SYSKEY = hwUNLOCK_KEY_0;\r
204         SYSKEY = hwUNLOCK_KEY_1;\r
205 \r
206         /* Read to start in sync. */\r
207         xOSCCONBits.w = OSCCON;\r
208         xOSCCONBits.PBDIV = 0;\r
209         xOSCCONBits.w |= hwPERIPHERAL_CLOCK_DIV_BY_2;\r
210 \r
211         /* Write back. */\r
212         OSCCON = xOSCCONBits.w;\r
213 \r
214         /* Ensure the write occurred. */\r
215         xOSCCONBits.w = OSCCON;\r
216 \r
217         /* Lock again. */\r
218         SYSKEY = hwLOCK_KEY;\r
219 \r
220         /* Resume DMA activity. */\r
221         if( ulDMAStatus == 0 )\r
222         {\r
223                 DMACONCLR=_DMACON_SUSPEND_MASK;\r
224         }\r
225 }\r
226 /*-----------------------------------------------------------*/\r
227 \r
228 static void prvConfigureWaitStates( void )\r
229 {\r
230 unsigned long ulSystemClock = configCPU_CLOCK_HZ - 1;\r
231 unsigned long ulWaitStates, ulCHECONVal;\r
232 \r
233         /* 1 wait state for every hwMAX_FLASH_SPEED MHz. */\r
234         ulWaitStates = 0;\r
235 \r
236         while( ulSystemClock > hwMAX_FLASH_SPEED )\r
237         {\r
238                 ulWaitStates++;\r
239                 ulSystemClock -= hwMAX_FLASH_SPEED;\r
240         }\r
241 \r
242         /* Obtain current CHECON value. */\r
243         ulCHECONVal = CHECON;\r
244 \r
245         /* Clear the wait state bits, then set the calculated wait state bits. */\r
246         ulCHECONVal &= ~hwCHECON_WAIT_STAT_BITS;\r
247         ulCHECONVal |= ulWaitStates;\r
248 \r
249         /* Write back the new value. */\r
250         CHECON = ulWaitStates;\r
251 }\r
252 /*-----------------------------------------------------------*/\r
253 \r
254 static void __attribute__ ((nomips16)) prvKSeg0CacheOn( void )\r
255 {\r
256 unsigned long ulValue;\r
257 \r
258         __asm volatile( "mfc0 %0, $16, 0" :  "=r"( ulValue ) );\r
259         ulValue = ( ulValue & ~0x07) | 0x03;\r
260         __asm volatile( "mtc0 %0, $16, 0" :: "r" ( ulValue ) );\r
261 }\r
262 \r
263 \r