1 //*****************************************************************************
2 //
3 //! @file am_hal_global.c
4 //!
5 //! @brief Locate global variables here.
6 //!
7 //! This module contains global variables that are used throughout the HAL.
8 //!
9 //! One use in particular is that it uses a global HAL flags variable that
10 //! contains flags used in various parts of the HAL.
11 //!
12 //! @addtogroup globals_4p Globals - HAL globals
13 //! @ingroup apollo4p_hal
14 //! @{
15 //
16 //*****************************************************************************
17
18 //*****************************************************************************
19 //
20 // Copyright (c) 2023, Ambiq Micro, Inc.
21 // All rights reserved.
22 //
23 // Redistribution and use in source and binary forms, with or without
24 // modification, are permitted provided that the following conditions are met:
25 //
26 // 1. Redistributions of source code must retain the above copyright notice,
27 // this list of conditions and the following disclaimer.
28 //
29 // 2. Redistributions in binary form must reproduce the above copyright
30 // notice, this list of conditions and the following disclaimer in the
31 // documentation and/or other materials provided with the distribution.
32 //
33 // 3. Neither the name of the copyright holder nor the names of its
34 // contributors may be used to endorse or promote products derived from this
35 // software without specific prior written permission.
36 //
37 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
41 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 // POSSIBILITY OF SUCH DAMAGE.
48 //
49 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package.
50 //
51 //*****************************************************************************
52
53 #include <stdint.h>
54 #include <stdbool.h>
55 #include "am_mcu_apollo.h"
56
57 //*****************************************************************************
58 //
59 // Global Variables
60 //
61 //*****************************************************************************
62
63 //*****************************************************************************
64 //
65 // Version information
66 //
67 //*****************************************************************************
68 const uint8_t g_ui8HALcompiler[] = COMPILER_VERSION;
69 const am_hal_version_t g_ui32HALversion =
70 {
71 .s.bAMREGS = false,
72 .s.Major = AM_HAL_VERSION_MAJ,
73 .s.Minor = AM_HAL_VERSION_MIN,
74 .s.Revision = AM_HAL_VERSION_REV
75 };
76
77 #ifdef APOLLO4_FPGA
78 uint32_t g_ui32FPGAfreqMHz = APOLLO4_FPGA;
79
80 //
81 // Use this function to set an FPGA frequency at run-time - avoids
82 // having to rebuild the entire HAL.
83 //
am_hal_global_FPGAfreqSet(uint32_t ui32FPGAfreqMHz)84 void am_hal_global_FPGAfreqSet(uint32_t ui32FPGAfreqMHz)
85 {
86 if ( ui32FPGAfreqMHz >= 1000000 )
87 {
88 ui32FPGAfreqMHz /= 1000000;
89 }
90
91 g_ui32FPGAfreqMHz = ui32FPGAfreqMHz;
92 } // am_hal_global_FFGAfreqSet()
93
94 #endif // APOLLO4_FPGA
95
96 //*****************************************************************************
97 //
98 // Static function for reading the timer value.
99 //
100 //*****************************************************************************
101 #if (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION < 6000000)
102 __asm void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])103 am_hal_triple_read( uint32_t ui32TimerAddr, uint32_t ui32Data[])
104 {
105 push {r1, r4} // Save r1=ui32Data, r4
106 mrs r4, PRIMASK // Save current interrupt state
107 cpsid i // Disable INTs while reading the reg
108 ldr r1, [r0, #0] // Read the designated register 3 times
109 ldr r2, [r0, #0] // "
110 ldr r3, [r0, #0] // "
111 msr PRIMASK, r4 // Restore interrupt state
112 pop {r0, r4} // Get r0=ui32Data, restore r4
113 str r1, [r0, #0] // Store 1st read value to array
114 str r2, [r0, #4] // Store 2nd read value to array
115 str r3, [r0, #8] // Store 3rd read value to array
116 bx lr // Return to caller
117 }
118 #elif (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION >= 6000000)
119 void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])120 am_hal_triple_read(uint32_t ui32TimerAddr, uint32_t ui32Data[])
121 {
122 __asm (
123 " push {R1, R4}\n"
124 " mrs R4, PRIMASK\n"
125 " cpsid i\n"
126 " nop\n"
127 " ldr R1, [R0, #0]\n"
128 " ldr R2, [R0, #0]\n"
129 " ldr R3, [R0, #0]\n"
130 " msr PRIMASK, r4\n"
131 " pop {R0, R4}\n"
132 " str R1, [R0, #0]\n"
133 " str R2, [R0, #4]\n"
134 " str R3, [R0, #8]\n"
135 :
136 : [ui32TimerAddr] "r" (ui32TimerAddr),
137 [ui32Data] "r" (&ui32Data[0])
138 : "r0", "r1", "r2", "r3", "r4"
139 );
140 }
141 #elif defined(__GNUC_STDC_INLINE__)
142 __attribute__((naked))
143 void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])144 am_hal_triple_read(uint32_t ui32TimerAddr, uint32_t ui32Data[])
145 {
146 __asm
147 (
148 " push {r1, r4}\n" // Save r1=ui32Data, r4
149 " mrs r4, PRIMASK \n" // Save current interrupt state
150 " cpsid i \n" // Disable INTs while reading the reg
151 " ldr r1, [r0, #0]\n" // Read the designated register 3 times
152 " ldr r2, [r0, #0]\n" // "
153 " ldr r3, [r0, #0]\n" // "
154 " msr PRIMASK, r4 \n" // Restore interrupt state
155 " pop {r0, r4}\n" // Get r0=ui32Data, restore r4
156 " str r1, [r0, #0]\n" // Store 1st read value to array
157 " str r2, [r0, #4]\n" // Store 2nd read value to array
158 " str r3, [r0, #8]\n" // Store 3rd read value to array
159 " bx lr \n" // Return to caller
160 );
161 }
162 #elif defined(__IAR_SYSTEMS_ICC__)
163 #pragma diag_suppress = Pe940 // Suppress IAR compiler warning about missing
164 // return statement on a non-void function
165 __stackless void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])166 am_hal_triple_read( uint32_t ui32TimerAddr, uint32_t ui32Data[])
167 {
168 __asm(" push {r1, r4} "); // Save r1=ui32Data, r4
169 __asm(" mrs r4, PRIMASK "); // Save current interrupt state
170 __asm(" cpsid i "); // Disable INTs while reading the reg
171 __asm(" ldr r1, [r0, #0]"); // Read the designated register 3 times
172 __asm(" ldr r2, [r0, #0]"); // "
173 __asm(" ldr r3, [r0, #0]"); // "
174 __asm(" msr PRIMASK, r4 "); // Restore interrupt state
175 __asm(" pop {r0, r4} "); // Get r0=ui32Data, restore r4
176 __asm(" str r1, [r0, #0]"); // Store 1st read value to array
177 __asm(" str r2, [r0, #4]"); // Store 2nd read value to array
178 __asm(" str r3, [r0, #8]"); // Store 3rd read value to array
179 __asm(" bx lr "); // Return to caller
180 }
181 #pragma diag_default = Pe940 // Restore IAR compiler warning
182 #else
183 #error Compiler is unknown, please contact Ambiq support team
184 #endif
185
186 //*****************************************************************************
187 //
188 // End Doxygen group.
189 //! @}
190 //
191 //*****************************************************************************
192