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