1 /* 2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 /** 16 **************************************************************************************** 17 * 18 * @file ll.h 19 * 20 * @brief Declaration of low level functions. 21 * 22 **************************************************************************************** 23 */ 24 25 #ifndef LL_H_ 26 #define LL_H_ 27 28 #include <stdint.h> 29 #include "arch.h" 30 #include "chip.h" 31 32 /** @brief Enable interrupts globally in the system. 33 * This macro must be used when the initialization phase is over and the interrupts 34 * can start being handled by the system. 35 */ 36 #define GLOBAL_INT_START() __enable_irq() 37 38 /** @brief Disable interrupts globally in the system. 39 * This macro must be used when the system wants to disable all the interrupt 40 * it could handle. 41 */ 42 #define GLOBAL_INT_STOP() __disable_irq() 43 44 45 /** @brief Disable interrupts globally in the system. 46 * This macro must be used in conjunction with the @ref GLOBAL_INT_RESTORE macro since this 47 * last one will close the brace that the current macro opens. This means that both 48 * macros must be located at the same scope level. 49 */ 50 51 #define GLOBAL_INT_DISABLE() \ 52 do { \ 53 uint32_t critical_interrupts_enabled = ((__get_PRIMASK() & 0x1) == 0); \ 54 if (critical_interrupts_enabled) { \ 55 __disable_irq(); \ 56 } 57 58 59 /** @brief Restore interrupts from the previous global disable. 60 * @sa GLOBAL_INT_DISABLE 61 */ 62 63 #define GLOBAL_INT_RESTORE() \ 64 if (critical_interrupts_enabled) { \ 65 __enable_irq(); \ 66 } \ 67 } while(0) 68 69 /** @brief Invoke the wait for interrupt procedure of the processor. 70 * 71 * @warning It is suggested that this macro is called while the interrupts are disabled 72 * to have performed the checks necessary to decide to move to sleep mode. 73 * 74 */ 75 #define WFI() \ 76 do { \ 77 GLOBAL_INT_DISABLE(); \ 78 __WFI(); \ 79 GLOBAL_INT_RESTORE(); \ 80 } while (0) 81 global_irq_lock(void)82__STATIC_FORCEINLINE uint32_t global_irq_lock(void) 83 { 84 uint32_t pmask = __get_PRIMASK(); 85 if ((pmask & 0x1) == 0) { 86 __disable_irq(); 87 } 88 return pmask; 89 } 90 global_irq_unlock(uint32_t pmask)91__STATIC_FORCEINLINE void global_irq_unlock(uint32_t pmask) 92 { 93 if ((pmask & 0x1) == 0) { 94 __enable_irq(); 95 } 96 } 97 98 /** 99 * Mark the start of a critical section 100 * 101 * On the first call to enter a critical section this function MUST store the 102 * state of any interrupts or other application settings it will modify to 103 * facilitate the critical section. 104 */ 105 void critical_section_start(void); 106 107 /** Mark the end of a critical section. 108 * 109 * The purpose of this function is to restore any state that was modified upon 110 * entering the critical section, allowing other threads or interrupts to change 111 * the processor control. 112 */ 113 void critical_section_end(void); 114 115 116 #endif // LL_H_ 117