Mbed SDK for XRange SX1272 LoRa module
Dependents: XRangePingPong XRange-LoRaWAN-lmic-app lora-transceiver
core_caFunc.h
00001 /**************************************************************************//** 00002 * @file core_caFunc.h 00003 * @brief CMSIS Cortex-A Core Function Access Header File 00004 * @version V3.10 00005 * @date 9 May 2013 00006 * 00007 * @note 00008 * 00009 ******************************************************************************/ 00010 /* Copyright (c) 2009 - 2012 ARM LIMITED 00011 00012 All rights reserved. 00013 Redistribution and use in source and binary forms, with or without 00014 modification, are permitted provided that the following conditions are met: 00015 - Redistributions of source code must retain the above copyright 00016 notice, this list of conditions and the following disclaimer. 00017 - Redistributions in binary form must reproduce the above copyright 00018 notice, this list of conditions and the following disclaimer in the 00019 documentation and/or other materials provided with the distribution. 00020 - Neither the name of ARM nor the names of its contributors may be used 00021 to endorse or promote products derived from this software without 00022 specific prior written permission. 00023 * 00024 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00027 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 00028 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00029 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00030 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00031 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00032 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00033 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 POSSIBILITY OF SUCH DAMAGE. 00035 ---------------------------------------------------------------------------*/ 00036 00037 00038 #ifndef __CORE_CAFUNC_H__ 00039 #define __CORE_CAFUNC_H__ 00040 00041 00042 /* ########################### Core Function Access ########################### */ 00043 /** \ingroup CMSIS_Core_FunctionInterface 00044 \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions 00045 @{ 00046 */ 00047 00048 #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ 00049 /* ARM armcc specific functions */ 00050 00051 #if (__ARMCC_VERSION < 400677) 00052 #error "Please use ARM Compiler Toolchain V4.0.677 or later!" 00053 #endif 00054 00055 #define MODE_USR 0x10 00056 #define MODE_FIQ 0x11 00057 #define MODE_IRQ 0x12 00058 #define MODE_SVC 0x13 00059 #define MODE_MON 0x16 00060 #define MODE_ABT 0x17 00061 #define MODE_HYP 0x1A 00062 #define MODE_UND 0x1B 00063 #define MODE_SYS 0x1F 00064 00065 /** \brief Get APSR Register 00066 00067 This function returns the content of the APSR Register. 00068 00069 \return APSR Register value 00070 */ 00071 __STATIC_INLINE uint32_t __get_APSR(void) 00072 { 00073 register uint32_t __regAPSR __ASM("apsr"); 00074 return(__regAPSR); 00075 } 00076 00077 00078 /** \brief Get CPSR Register 00079 00080 This function returns the content of the CPSR Register. 00081 00082 \return CPSR Register value 00083 */ 00084 __STATIC_INLINE uint32_t __get_CPSR(void) 00085 { 00086 register uint32_t __regCPSR __ASM("cpsr"); 00087 return(__regCPSR); 00088 } 00089 00090 /** \brief Set Stack Pointer 00091 00092 This function assigns the given value to the current stack pointer. 00093 00094 \param [in] topOfStack Stack Pointer value to set 00095 */ 00096 register uint32_t __regSP __ASM("sp"); 00097 __STATIC_INLINE void __set_SP(uint32_t topOfStack) 00098 { 00099 __regSP = topOfStack; 00100 } 00101 00102 00103 /** \brief Get link register 00104 00105 This function returns the value of the link register 00106 00107 \return Value of link register 00108 */ 00109 register uint32_t __reglr __ASM("lr"); 00110 __STATIC_INLINE uint32_t __get_LR(void) 00111 { 00112 return(__reglr); 00113 } 00114 00115 /** \brief Set link register 00116 00117 This function sets the value of the link register 00118 00119 \param [in] lr LR value to set 00120 */ 00121 __STATIC_INLINE void __set_LR(uint32_t lr) 00122 { 00123 __reglr = lr; 00124 } 00125 00126 /** \brief Set Process Stack Pointer 00127 00128 This function assigns the given value to the USR/SYS Stack Pointer (PSP). 00129 00130 \param [in] topOfProcStack USR/SYS Stack Pointer value to set 00131 */ 00132 __STATIC_ASM void __set_PSP(uint32_t topOfProcStack) 00133 { 00134 ARM 00135 PRESERVE8 00136 00137 BIC R0, R0, #7 ;ensure stack is 8-byte aligned 00138 MRS R1, CPSR 00139 CPS #MODE_SYS ;no effect in USR mode 00140 MOV SP, R0 00141 MSR CPSR_c, R1 ;no effect in USR mode 00142 ISB 00143 BX LR 00144 00145 } 00146 00147 /** \brief Set User Mode 00148 00149 This function changes the processor state to User Mode 00150 00151 \param [in] topOfProcStack USR/SYS Stack Pointer value to set 00152 */ 00153 __STATIC_ASM void __set_CPS_USR(void) 00154 { 00155 ARM 00156 00157 CPS #MODE_USR 00158 BX LR 00159 } 00160 00161 00162 /** \brief Enable FIQ 00163 00164 This function enables FIQ interrupts by clearing the F-bit in the CPSR. 00165 Can only be executed in Privileged modes. 00166 */ 00167 #define __enable_fault_irq __enable_fiq 00168 00169 00170 /** \brief Disable FIQ 00171 00172 This function disables FIQ interrupts by setting the F-bit in the CPSR. 00173 Can only be executed in Privileged modes. 00174 */ 00175 #define __disable_fault_irq __disable_fiq 00176 00177 00178 /** \brief Get FPSCR 00179 00180 This function returns the current value of the Floating Point Status/Control register. 00181 00182 \return Floating Point Status/Control register value 00183 */ 00184 __STATIC_INLINE uint32_t __get_FPSCR(void) 00185 { 00186 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 00187 register uint32_t __regfpscr __ASM("fpscr"); 00188 return(__regfpscr); 00189 #else 00190 return(0); 00191 #endif 00192 } 00193 00194 00195 /** \brief Set FPSCR 00196 00197 This function assigns the given value to the Floating Point Status/Control register. 00198 00199 \param [in] fpscr Floating Point Status/Control value to set 00200 */ 00201 __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) 00202 { 00203 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 00204 register uint32_t __regfpscr __ASM("fpscr"); 00205 __regfpscr = (fpscr); 00206 #endif 00207 } 00208 00209 /** \brief Get FPEXC 00210 00211 This function returns the current value of the Floating Point Exception Control register. 00212 00213 \return Floating Point Exception Control register value 00214 */ 00215 __STATIC_INLINE uint32_t __get_FPEXC(void) 00216 { 00217 #if (__FPU_PRESENT == 1) 00218 register uint32_t __regfpexc __ASM("fpexc"); 00219 return(__regfpexc); 00220 #else 00221 return(0); 00222 #endif 00223 } 00224 00225 00226 /** \brief Set FPEXC 00227 00228 This function assigns the given value to the Floating Point Exception Control register. 00229 00230 \param [in] fpscr Floating Point Exception Control value to set 00231 */ 00232 __STATIC_INLINE void __set_FPEXC(uint32_t fpexc) 00233 { 00234 #if (__FPU_PRESENT == 1) 00235 register uint32_t __regfpexc __ASM("fpexc"); 00236 __regfpexc = (fpexc); 00237 #endif 00238 } 00239 00240 /** \brief Get CPACR 00241 00242 This function returns the current value of the Coprocessor Access Control register. 00243 00244 \return Coprocessor Access Control register value 00245 */ 00246 __STATIC_INLINE uint32_t __get_CPACR(void) 00247 { 00248 register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); 00249 return __regCPACR; 00250 } 00251 00252 /** \brief Set CPACR 00253 00254 This function assigns the given value to the Coprocessor Access Control register. 00255 00256 \param [in] cpacr Coporcessor Acccess Control value to set 00257 */ 00258 __STATIC_INLINE void __set_CPACR(uint32_t cpacr) 00259 { 00260 register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2"); 00261 __regCPACR = cpacr; 00262 __ISB(); 00263 } 00264 00265 /** \brief Get CBAR 00266 00267 This function returns the value of the Configuration Base Address register. 00268 00269 \return Configuration Base Address register value 00270 */ 00271 __STATIC_INLINE uint32_t __get_CBAR() { 00272 register uint32_t __regCBAR __ASM("cp15:4:c15:c0:0"); 00273 return(__regCBAR); 00274 } 00275 00276 /** \brief Get TTBR0 00277 00278 This function returns the value of the Configuration Base Address register. 00279 00280 \return Translation Table Base Register 0 value 00281 */ 00282 __STATIC_INLINE uint32_t __get_TTBR0() { 00283 register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); 00284 return(__regTTBR0); 00285 } 00286 00287 /** \brief Set TTBR0 00288 00289 This function assigns the given value to the Coprocessor Access Control register. 00290 00291 \param [in] ttbr0 Translation Table Base Register 0 value to set 00292 */ 00293 __STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) { 00294 register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0"); 00295 __regTTBR0 = ttbr0; 00296 __ISB(); 00297 } 00298 00299 /** \brief Get DACR 00300 00301 This function returns the value of the Domain Access Control Register. 00302 00303 \return Domain Access Control Register value 00304 */ 00305 __STATIC_INLINE uint32_t __get_DACR() { 00306 register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); 00307 return(__regDACR); 00308 } 00309 00310 /** \brief Set DACR 00311 00312 This function assigns the given value to the Coprocessor Access Control register. 00313 00314 \param [in] dacr Domain Access Control Register value to set 00315 */ 00316 __STATIC_INLINE void __set_DACR(uint32_t dacr) { 00317 register uint32_t __regDACR __ASM("cp15:0:c3:c0:0"); 00318 __regDACR = dacr; 00319 __ISB(); 00320 } 00321 00322 /******************************** Cache and BTAC enable ****************************************************/ 00323 00324 /** \brief Set SCTLR 00325 00326 This function assigns the given value to the System Control Register. 00327 00328 \param [in] sctlr System Control Register, value to set 00329 */ 00330 __STATIC_INLINE void __set_SCTLR(uint32_t sctlr) 00331 { 00332 register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); 00333 __regSCTLR = sctlr; 00334 } 00335 00336 /** \brief Get SCTLR 00337 00338 This function returns the value of the System Control Register. 00339 00340 \return System Control Register value 00341 */ 00342 __STATIC_INLINE uint32_t __get_SCTLR() { 00343 register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0"); 00344 return(__regSCTLR); 00345 } 00346 00347 /** \brief Enable Caches 00348 00349 Enable Caches 00350 */ 00351 __STATIC_INLINE void __enable_caches(void) { 00352 // Set I bit 12 to enable I Cache 00353 // Set C bit 2 to enable D Cache 00354 __set_SCTLR( __get_SCTLR() | (1 << 12) | (1 << 2)); 00355 } 00356 00357 /** \brief Disable Caches 00358 00359 Disable Caches 00360 */ 00361 __STATIC_INLINE void __disable_caches(void) { 00362 // Clear I bit 12 to disable I Cache 00363 // Clear C bit 2 to disable D Cache 00364 __set_SCTLR( __get_SCTLR() & ~(1 << 12) & ~(1 << 2)); 00365 __ISB(); 00366 } 00367 00368 /** \brief Enable BTAC 00369 00370 Enable BTAC 00371 */ 00372 __STATIC_INLINE void __enable_btac(void) { 00373 // Set Z bit 11 to enable branch prediction 00374 __set_SCTLR( __get_SCTLR() | (1 << 11)); 00375 __ISB(); 00376 } 00377 00378 /** \brief Disable BTAC 00379 00380 Disable BTAC 00381 */ 00382 __STATIC_INLINE void __disable_btac(void) { 00383 // Clear Z bit 11 to disable branch prediction 00384 __set_SCTLR( __get_SCTLR() & ~(1 << 11)); 00385 } 00386 00387 00388 /** \brief Enable MMU 00389 00390 Enable MMU 00391 */ 00392 __STATIC_INLINE void __enable_mmu(void) { 00393 // Set M bit 0 to enable the MMU 00394 // Set AFE bit to enable simplified access permissions model 00395 // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking 00396 __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); 00397 __ISB(); 00398 } 00399 00400 /** \brief Enable MMU 00401 00402 Enable MMU 00403 */ 00404 __STATIC_INLINE void __disable_mmu(void) { 00405 // Clear M bit 0 to disable the MMU 00406 __set_SCTLR( __get_SCTLR() & ~1); 00407 __ISB(); 00408 } 00409 00410 /******************************** TLB maintenance operations ************************************************/ 00411 /** \brief Invalidate the whole tlb 00412 00413 TLBIALL. Invalidate the whole tlb 00414 */ 00415 00416 __STATIC_INLINE void __ca9u_inv_tlb_all(void) { 00417 register uint32_t __TLBIALL __ASM("cp15:0:c8:c7:0"); 00418 __TLBIALL = 0; 00419 __DSB(); 00420 __ISB(); 00421 } 00422 00423 /******************************** BTB maintenance operations ************************************************/ 00424 /** \brief Invalidate entire branch predictor array 00425 00426 BPIALL. Branch Predictor Invalidate All. 00427 */ 00428 00429 __STATIC_INLINE void __v7_inv_btac(void) { 00430 register uint32_t __BPIALL __ASM("cp15:0:c7:c5:6"); 00431 __BPIALL = 0; 00432 __DSB(); //ensure completion of the invalidation 00433 __ISB(); //ensure instruction fetch path sees new state 00434 } 00435 00436 00437 /******************************** L1 cache operations ******************************************************/ 00438 00439 /** \brief Invalidate the whole I$ 00440 00441 ICIALLU. Instruction Cache Invalidate All to PoU 00442 */ 00443 __STATIC_INLINE void __v7_inv_icache_all(void) { 00444 register uint32_t __ICIALLU __ASM("cp15:0:c7:c5:0"); 00445 __ICIALLU = 0; 00446 __DSB(); //ensure completion of the invalidation 00447 __ISB(); //ensure instruction fetch path sees new I cache state 00448 } 00449 00450 /** \brief Clean D$ by MVA 00451 00452 DCCMVAC. Data cache clean by MVA to PoC 00453 */ 00454 __STATIC_INLINE void __v7_clean_dcache_mva(void *va) { 00455 register uint32_t __DCCMVAC __ASM("cp15:0:c7:c10:1"); 00456 __DCCMVAC = (uint32_t)va; 00457 __DMB(); //ensure the ordering of data cache maintenance operations and their effects 00458 } 00459 00460 /** \brief Invalidate D$ by MVA 00461 00462 DCIMVAC. Data cache invalidate by MVA to PoC 00463 */ 00464 __STATIC_INLINE void __v7_inv_dcache_mva(void *va) { 00465 register uint32_t __DCIMVAC __ASM("cp15:0:c7:c6:1"); 00466 __DCIMVAC = (uint32_t)va; 00467 __DMB(); //ensure the ordering of data cache maintenance operations and their effects 00468 } 00469 00470 /** \brief Clean and Invalidate D$ by MVA 00471 00472 DCCIMVAC. Data cache clean and invalidate by MVA to PoC 00473 */ 00474 __STATIC_INLINE void __v7_clean_inv_dcache_mva(void *va) { 00475 register uint32_t __DCCIMVAC __ASM("cp15:0:c7:c14:1"); 00476 __DCCIMVAC = (uint32_t)va; 00477 __DMB(); //ensure the ordering of data cache maintenance operations and their effects 00478 } 00479 00480 /** \brief 00481 * Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency. 00482 */ 00483 #pragma push 00484 #pragma arm 00485 __STATIC_ASM void __v7_all_cache(uint32_t op) { 00486 ARM 00487 00488 PUSH {R4-R11} 00489 00490 MRC p15, 1, R6, c0, c0, 1 // Read CLIDR 00491 ANDS R3, R6, #0x07000000 // Extract coherency level 00492 MOV R3, R3, LSR #23 // Total cache levels << 1 00493 BEQ Finished // If 0, no need to clean 00494 00495 MOV R10, #0 // R10 holds current cache level << 1 00496 Loop1 ADD R2, R10, R10, LSR #1 // R2 holds cache "Set" position 00497 MOV R1, R6, LSR R2 // Bottom 3 bits are the Cache-type for this level 00498 AND R1, R1, #7 // Isolate those lower 3 bits 00499 CMP R1, #2 00500 BLT Skip // No cache or only instruction cache at this level 00501 00502 MCR p15, 2, R10, c0, c0, 0 // Write the Cache Size selection register 00503 ISB // ISB to sync the change to the CacheSizeID reg 00504 MRC p15, 1, R1, c0, c0, 0 // Reads current Cache Size ID register 00505 AND R2, R1, #7 // Extract the line length field 00506 ADD R2, R2, #4 // Add 4 for the line length offset (log2 16 bytes) 00507 LDR R4, =0x3FF 00508 ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned) 00509 CLZ R5, R4 // R5 is the bit position of the way size increment 00510 LDR R7, =0x7FFF 00511 ANDS R7, R7, R1, LSR #13 // R7 is the max number of the index size (right aligned) 00512 00513 Loop2 MOV R9, R4 // R9 working copy of the max way size (right aligned) 00514 00515 Loop3 ORR R11, R10, R9, LSL R5 // Factor in the Way number and cache number into R11 00516 ORR R11, R11, R7, LSL R2 // Factor in the Set number 00517 CMP R0, #0 00518 BNE Dccsw 00519 MCR p15, 0, R11, c7, c6, 2 // DCISW. Invalidate by Set/Way 00520 B cont 00521 Dccsw CMP R0, #1 00522 BNE Dccisw 00523 MCR p15, 0, R11, c7, c10, 2 // DCCSW. Clean by Set/Way 00524 B cont 00525 Dccisw MCR p15, 0, R11, c7, c14, 2 // DCCISW, Clean and Invalidate by Set/Way 00526 cont SUBS R9, R9, #1 // Decrement the Way number 00527 BGE Loop3 00528 SUBS R7, R7, #1 // Decrement the Set number 00529 BGE Loop2 00530 Skip ADD R10, R10, #2 // increment the cache number 00531 CMP R3, R10 00532 BGT Loop1 00533 00534 Finished 00535 DSB 00536 POP {R4-R11} 00537 BX lr 00538 00539 } 00540 #pragma pop 00541 00542 /** \brief __v7_all_cache - helper function 00543 00544 */ 00545 00546 /** \brief Invalidate the whole D$ 00547 00548 DCISW. Invalidate by Set/Way 00549 */ 00550 00551 __STATIC_INLINE void __v7_inv_dcache_all(void) { 00552 __v7_all_cache(0); 00553 } 00554 00555 /** \brief Clean the whole D$ 00556 00557 DCCSW. Clean by Set/Way 00558 */ 00559 00560 __STATIC_INLINE void __v7_clean_dcache_all(void) { 00561 __v7_all_cache(1); 00562 } 00563 00564 /** \brief Clean and invalidate the whole D$ 00565 00566 DCCISW. Clean and Invalidate by Set/Way 00567 */ 00568 00569 __STATIC_INLINE void __v7_clean_inv_dcache_all(void) { 00570 __v7_all_cache(2); 00571 } 00572 00573 #include "core_ca_mmu.h" 00574 00575 #elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/ 00576 00577 #error IAR Compiler support not implemented for Cortex-A 00578 00579 #elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ 00580 00581 //#error GNU Compiler support not implemented for Cortex-A 00582 00583 #elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/ 00584 00585 #error TASKING Compiler support not implemented for Cortex-A 00586 00587 #endif 00588 00589 /*@} end of CMSIS_Core_RegAccFunctions */ 00590 00591 00592 #endif /* __CORE_CAFUNC_H__ */
Generated on Tue Jul 12 2022 19:26:58 by 1.7.2