EDF - OnePIC MCU
v1.1.0
|
00001 /****************************************************************************** 00002 00003 File Name: TimeDelay.c 00004 Dependencies: None 00005 Processor: PIC18/PIC24/dsPIC30/dsPIC33/PIC32 00006 Compiler: C30 v3.12 00007 Company: Microchip Technology, Inc. 00008 00009 Copyright (C) 2010 Microchip Technology Inc. All rights reserved. 00010 00011 Microchip licenses to you the right to use, modify, copy and distribute 00012 Software only when embedded on a Microchip microcontroller or digital signal 00013 controller that is integrated into your product or third party product 00014 (pursuant to the sublicense terms in the accompanying license agreement). 00015 00016 You should refer to the license agreement accompanying this Software for 00017 additional information regarding your rights and obligations. 00018 00019 SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 00020 EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF 00021 MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. 00022 IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER 00023 CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR 00024 OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES 00025 INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR 00026 CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF 00027 SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES 00028 (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. 00029 00030 Author Date Comments 00031 -------------------------------------------------------------------------------- 00032 AKN 2009.10.14 FILE CREATED 00033 AKN 2009.10.15 CHANGED C18 DELAY ROUTINE TO DECREMENT ENTIRE NUMBER OF CYCLES 00034 AKN 2009.10.19 CHANGED C30 DELAY ROUTINE TO MATCH C18 IMPLEMENTATION 00035 AKN 2009.10.26 ADDED C32 DELAY ROUTINE TO MATCH C18 IMPLEMENTATION 00036 AKN 2009.10.27 CONSOLIDATED C30 AND C32 IMPLEMENTATIONS, ADDED PADDING TO 00037 MAKE C30 DELAYS MORE ACCURATE 00038 PAT 2010.01.26 CONVERTED LOCALS TO VOLATILE 00039 PAT 2010.03.07 ADDED include "Compiler.h" 00040 *******************************************************************************/ 00041 00046 #if defined(__PIC32MX__) 00047 #include <plib.h> 00048 #endif 00049 #include "bsp.h" 00050 #include "Compiler.h" 00051 //#include "HardwareProfile.h" 00052 00053 #include "TimeDelay.h" 00054 00059 void Delay10us(UINT32 tenMicroSecondCounter) { 00060 volatile INT32 cyclesRequiredForEntireDelay; 00061 #if defined (__PICC__) 00062 uint8_t i; 00063 for (i = 0; i != tenMicroSecondCounter; i++) 00064 __delay_us(10); 00065 // if (GetInstructionClock() <= 2500000) { 00066 // 00067 // } 00068 #elif defined(__18CXX) 00069 00070 if (GetInstructionClock() <= 2500000) //for all FCY speeds under 2MHz (FOSC <= 10MHz) 00071 { 00072 //26 cycles burned through this path (includes return to caller). 00073 //For FOSC == 1MHZ, it takes 104us. 00074 //For FOSC == 4MHZ, it takes 26us 00075 //For FOSC == 8MHZ, it takes 13us. 00076 //For FOSC == 10MHZ, it takes 10.5us. 00077 } else { 00078 //14 cycles burned to this point. 00079 00080 //We want to pre-calculate number of cycles required to delay 10us * tenMicroSecondCounter using a 1 cycle granule. 00081 cyclesRequiredForEntireDelay = (INT32) (GetInstructionClock() / 100000) * tenMicroSecondCounter; 00082 00083 //We subtract all the cycles used up until we reach the while loop below, where each loop cycle count is subtracted. 00084 //Also we subtract the 22 cycle function return. 00085 cyclesRequiredForEntireDelay -= (153 + 22); 00086 00087 if (cyclesRequiredForEntireDelay <= 45) { 00088 // If we have exceeded the cycle count already, bail! Best compromise between FOSC == 12MHz and FOSC == 24MHz. 00089 } else { 00090 //Try as you may, you can't get out of this heavier-duty case under 30us. ;] 00091 00092 while (cyclesRequiredForEntireDelay > 0) //153 cycles used to this point. 00093 { 00094 Nop(); //Delay one instruction cycle at a time, not absolutely necessary. 00095 cyclesRequiredForEntireDelay -= 42; //Subtract cycles burned while doing each delay stage, 42 in this case. 00096 } 00097 } 00098 } 00099 00100 #elif defined(__C30__) || defined(__PIC32MX__) 00101 00102 if (GetInstructionClock() <= 500000) //for all FCY speeds under 500KHz (FOSC <= 1MHz) 00103 { 00104 //10 cycles burned through this path (includes return to caller). 00105 //For FOSC == 1MHZ, it takes 5us. 00106 //For FOSC == 4MHZ, it takes 0.5us 00107 //For FOSC == 8MHZ, it takes 0.25us. 00108 //For FOSC == 10MHZ, it takes 0.2us. 00109 } else { 00110 //7 cycles burned to this point. 00111 00112 //We want to pre-calculate number of cycles required to delay 10us * tenMicroSecondCounter using a 1 cycle granule. 00113 cyclesRequiredForEntireDelay = (INT32) (GetInstructionClock() / 100000) * tenMicroSecondCounter; 00114 00115 #if defined(__C30__) 00116 //We subtract all the cycles used up until we reach the while loop below, where each loop cycle count is subtracted. 00117 //Also we subtract the 5 cycle function return. 00118 cyclesRequiredForEntireDelay -= 44; //(29 + 5) + 10 cycles padding 00119 #elif defined(__PIC32MX__) 00120 //We subtract all the cycles used up until we reach the while loop below, where each loop cycle count is subtracted. 00121 //Also we subtract the 5 cycle function return. 00122 cyclesRequiredForEntireDelay -= 24; //(19 + 5) 00123 #endif 00124 00125 if (cyclesRequiredForEntireDelay <= 0) { 00126 // If we have exceeded the cycle count already, bail! 00127 } else { 00128 while (cyclesRequiredForEntireDelay > 0) //19 cycles used to this point. 00129 { 00130 #if defined(__C30__) 00131 cyclesRequiredForEntireDelay -= 11; //Subtract cycles burned while doing each delay stage, 12 in this case. Add one cycle as padding. 00132 #elif defined(__PIC32MX__) 00133 cyclesRequiredForEntireDelay -= 8; //Subtract cycles burned while doing each delay stage, 8 in this case. 00134 #endif 00135 } 00136 } 00137 } 00138 #endif 00139 } 00140 00145 void DelayMs(UINT16 ms) { 00146 #if defined(__PICC__) 00147 uint16_t i; 00148 for (i = ms; i != 0; i--) 00149 __delay_ms(1); 00150 // INT32 cyclesRequiredForEntireDelay; 00151 // // We want to pre-calculate number of cycles required to delay 1ms, using a 1 cycle granule. 00152 // cyclesRequiredForEntireDelay = (unsigned long) (GetInstructionClock() / 1000) * ms; 00153 // 00154 // // We subtract all the cycles used up until we reach the while loop below, where each loop cycle count is subtracted. 00155 // // Also we subtract the 22 cycle function return. 00156 // cyclesRequiredForEntireDelay -= (148 + 22); 00157 // 00158 // if (cyclesRequiredForEntireDelay <= (170 + 25)) { 00159 // return; // If we have exceeded the cycle count already, bail! 00160 // } else { 00161 // while (cyclesRequiredForEntireDelay > 0) //148 cycles used to this point. 00162 // { 00163 // NOP(); // Delay one instruction cycle at a time, not absolutely necessary. 00164 // cyclesRequiredForEntireDelay -= 26; // Subtract cycles burned while doing each delay stage, 39 in this case. 00165 // } 00166 // } 00167 #elif defined(__18CXX) 00168 00169 INT32 cyclesRequiredForEntireDelay; 00170 00171 // We want to pre-calculate number of cycles required to delay 1ms, using a 1 cycle granule. 00172 cyclesRequiredForEntireDelay = (signed long) (GetInstructionClock() / 1000) * ms; 00173 00174 // We subtract all the cycles used up until we reach the while loop below, where each loop cycle count is subtracted. 00175 // Also we subtract the 22 cycle function return. 00176 cyclesRequiredForEntireDelay -= (148 + 22); 00177 00178 if (cyclesRequiredForEntireDelay <= (170 + 25)) { 00179 return; // If we have exceeded the cycle count already, bail! 00180 } else { 00181 while (cyclesRequiredForEntireDelay > 0) //148 cycles used to this point. 00182 { 00183 Nop(); // Delay one instruction cycle at a time, not absolutely necessary. 00184 cyclesRequiredForEntireDelay -= 39; // Subtract cycles burned while doing each delay stage, 39 in this case. 00185 } 00186 } 00187 00188 00189 #elif defined(__C30__) || defined(__PIC32MX__) 00190 00191 volatile UINT8 i; 00192 00193 while (ms--) { 00194 i = 4; 00195 while (i--) { 00196 Delay10us(25); 00197 } 00198 } 00199 #endif 00200 } 00201