]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/PIC32MX_MPLAB/ConfigPerformance.c
Update version number in readiness for V10.3.0 release. Sync SVN with reviewed releas...
[freertos] / FreeRTOS / Demo / PIC32MX_MPLAB / ConfigPerformance.c
1 /*\r
2  * FreeRTOS Kernel V10.3.0\r
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 /*\r
29  * This file implements functions to access and manipulate the PIC32 hardware\r
30  * without reliance on third party library functions that may be liable to\r
31  * change.\r
32  */\r
33 \r
34 /* FreeRTOS includes. */\r
35 #include "FreeRTOS.h"\r
36 \r
37 /* Demo includes. */\r
38 #include "ConfigPerformance.h"\r
39 \r
40 /* Hardware specific definitions. */\r
41 #define hwCHECON_PREFEN_BITS                    ( 0x03UL << 0x04UL )\r
42 #define hwCHECON_WAIT_STAT_BITS                 ( 0x07UL << 0UL )\r
43 #define hwMAX_FLASH_SPEED                               ( 30000000UL )\r
44 #define hwPERIPHERAL_CLOCK_DIV_BY_2             ( 1UL << 0x13UL )\r
45 #define hwUNLOCK_KEY_0                                  ( 0xAA996655UL )\r
46 #define hwUNLOCK_KEY_1                                  ( 0x556699AAUL )\r
47 #define hwLOCK_KEY                                              ( 0x33333333UL )\r
48 #define hwGLOBAL_INTERRUPT_BIT                  ( 0x01UL )\r
49 #define hwBEV_BIT                                               ( 0x00400000 )\r
50 #define hwEXL_BIT                                               ( 0x00000002 )\r
51 #define hwIV_BIT                                                ( 0x00800000 )\r
52 \r
53 /*\r
54  * Set the flash wait states for the configured CPU clock speed.\r
55  */\r
56 static void prvConfigureWaitStates( void );\r
57 \r
58 /*\r
59  * Use a divisor of 2 on the peripheral bus.\r
60  */\r
61 static void prvConfigurePeripheralBus( void );\r
62 \r
63 /*\r
64  * Enable the cache.\r
65  */\r
66 static void __attribute__ ((nomips16)) prvKSeg0CacheOn( void );\r
67 \r
68 /*-----------------------------------------------------------*/\r
69 \r
70 void vHardwareConfigurePerformance( void )\r
71 {\r
72 unsigned long ulStatus;\r
73 #ifdef _PCACHE\r
74         unsigned long ulCacheStatus;\r
75 #endif\r
76 \r
77         /* Disable interrupts - note taskDISABLE_INTERRUPTS() cannot be used here as\r
78         FreeRTOS does not globally disable interrupt. */\r
79         ulStatus = _CP0_GET_STATUS();\r
80         _CP0_SET_STATUS( ulStatus & ~hwGLOBAL_INTERRUPT_BIT );\r
81 \r
82         prvConfigurePeripheralBus();\r
83         prvConfigureWaitStates();\r
84 \r
85         /* Disable DRM wait state. */\r
86         BMXCONCLR = _BMXCON_BMXWSDRM_MASK;\r
87 \r
88         #ifdef _PCACHE\r
89         {\r
90                 /* Read the current CHECON value. */\r
91                 ulCacheStatus = CHECON;\r
92 \r
93                 /* All the PREFEN bits are being set, so no need to clear first. */\r
94                 ulCacheStatus |= hwCHECON_PREFEN_BITS;\r
95 \r
96                 /* Write back the new value. */\r
97                 CHECON = ulCacheStatus;\r
98                 prvKSeg0CacheOn();\r
99         }\r
100         #endif\r
101 \r
102         /* Reset the status register back to its original value so the original\r
103         interrupt enable status is retored. */\r
104         _CP0_SET_STATUS( ulStatus );\r
105 }\r
106 /*-----------------------------------------------------------*/\r
107 \r
108 void vHardwareUseMultiVectoredInterrupts( void )\r
109 {\r
110 unsigned long ulStatus, ulCause;\r
111 extern unsigned long _ebase_address[];\r
112 \r
113         /* Get current status. */\r
114         ulStatus = _CP0_GET_STATUS();\r
115 \r
116         /* Disable interrupts. */\r
117         ulStatus &= ~hwGLOBAL_INTERRUPT_BIT;\r
118 \r
119         /* Set BEV bit. */\r
120         ulStatus |= hwBEV_BIT;\r
121 \r
122         /* Write status back. */\r
123         _CP0_SET_STATUS( ulStatus );\r
124 \r
125         /* Setup EBase. */\r
126         _CP0_SET_EBASE( ( unsigned long ) _ebase_address );\r
127         \r
128         /* Space vectors by 0x20 bytes. */\r
129         _CP0_XCH_INTCTL( 0x20 );\r
130 \r
131         /* Set the IV bit in the CAUSE register. */\r
132         ulCause = _CP0_GET_CAUSE();\r
133         ulCause |= hwIV_BIT;\r
134         _CP0_SET_CAUSE( ulCause );\r
135 \r
136         /* Clear BEV and EXL bits in status. */\r
137         ulStatus &= ~( hwBEV_BIT | hwEXL_BIT );\r
138         _CP0_SET_STATUS( ulStatus );\r
139 \r
140         /* Set MVEC bit. */\r
141         INTCONbits.MVEC = 1;\r
142         \r
143         /* Finally enable interrupts again. */\r
144         ulStatus |= hwGLOBAL_INTERRUPT_BIT;\r
145         _CP0_SET_STATUS( ulStatus );\r
146 }\r
147 /*-----------------------------------------------------------*/\r
148 \r
149 static void prvConfigurePeripheralBus( void )\r
150 {\r
151 unsigned long ulDMAStatus;\r
152 __OSCCONbits_t xOSCCONBits;\r
153 \r
154         /* Unlock after suspending. */\r
155         ulDMAStatus = DMACONbits.SUSPEND;\r
156         if( ulDMAStatus == 0 )\r
157         {\r
158                 DMACONSET = _DMACON_SUSPEND_MASK;\r
159 \r
160                 /* Wait until actually suspended. */\r
161                 while( DMACONbits.SUSPEND == 0 );\r
162         }\r
163 \r
164         SYSKEY = 0;\r
165         SYSKEY = hwUNLOCK_KEY_0;\r
166         SYSKEY = hwUNLOCK_KEY_1;\r
167 \r
168         /* Read to start in sync. */\r
169         xOSCCONBits.w = OSCCON;\r
170         xOSCCONBits.PBDIV = 0;\r
171         xOSCCONBits.w |= hwPERIPHERAL_CLOCK_DIV_BY_2;\r
172 \r
173         /* Write back. */\r
174         OSCCON = xOSCCONBits.w;\r
175 \r
176         /* Ensure the write occurred. */\r
177         xOSCCONBits.w = OSCCON;\r
178 \r
179         /* Lock again. */\r
180         SYSKEY = hwLOCK_KEY;\r
181 \r
182         /* Resume DMA activity. */\r
183         if( ulDMAStatus == 0 )\r
184         {\r
185                 DMACONCLR=_DMACON_SUSPEND_MASK;\r
186         }\r
187 }\r
188 /*-----------------------------------------------------------*/\r
189 \r
190 static void prvConfigureWaitStates( void )\r
191 {\r
192 unsigned long ulSystemClock = configCPU_CLOCK_HZ - 1;\r
193 unsigned long ulWaitStates, ulCHECONVal;\r
194 \r
195         /* 1 wait state for every hwMAX_FLASH_SPEED MHz. */\r
196         ulWaitStates = 0;\r
197 \r
198         while( ulSystemClock > hwMAX_FLASH_SPEED )\r
199         {\r
200                 ulWaitStates++;\r
201                 ulSystemClock -= hwMAX_FLASH_SPEED;\r
202         }\r
203 \r
204         /* Obtain current CHECON value. */\r
205         ulCHECONVal = CHECON;\r
206 \r
207         /* Clear the wait state bits, then set the calculated wait state bits. */\r
208         ulCHECONVal &= ~hwCHECON_WAIT_STAT_BITS;\r
209         ulCHECONVal |= ulWaitStates;\r
210 \r
211         /* Write back the new value. */\r
212         CHECON = ulWaitStates;\r
213 }\r
214 /*-----------------------------------------------------------*/\r
215 \r
216 static void __attribute__ ((nomips16)) prvKSeg0CacheOn( void )\r
217 {\r
218 unsigned long ulValue;\r
219 \r
220         __asm volatile( "mfc0 %0, $16, 0" :  "=r"( ulValue ) );\r
221         ulValue = ( ulValue & ~0x07) | 0x03;\r
222         __asm volatile( "mtc0 %0, $16, 0" :: "r" ( ulValue ) );\r
223 }\r
224 \r
225 \r