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