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 global Global - Global Varables
13 //! @ingroup apollo3_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_3_1_1-10cda4b5e0 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 //
60 //! Global Variables
61 //
62 //*****************************************************************************
63 
64 //*****************************************************************************
65 //
66 //! Version information
67 //
68 //*****************************************************************************
69 const uint8_t  g_ui8HALcompiler[] = COMPILER_VERSION;
70 const am_hal_version_t g_ui32HALversion =
71 {
72     .s.bAMREGS  = false,
73     .s.Major    = AM_HAL_VERSION_MAJ,
74     .s.Minor    = AM_HAL_VERSION_MIN,
75     .s.Revision = AM_HAL_VERSION_REV
76 };
77 
78 //*****************************************************************************
79 //
80 //! @brief Static function for reading the timer value.
81 //!
82 //! @param ui32TimerAddr
83 //! @param ui32Data
84 //
85 //*****************************************************************************
86 #if (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION < 6000000)
87 __asm void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])88 am_hal_triple_read( uint32_t ui32TimerAddr, uint32_t ui32Data[])
89 {
90     push    {r1, r4}                // Save r1=ui32Data, r4
91     mrs     r4, PRIMASK             // Save current interrupt state
92     cpsid   i                       // Disable INTs while reading the reg
93     ldr     r1, [r0, #0]            // Read the designated register 3 times
94     ldr     r2, [r0, #0]            //  "
95     ldr     r3, [r0, #0]            //  "
96     msr     PRIMASK, r4             // Restore interrupt state
97     pop     {r0, r4}                // Get r0=ui32Data, restore r4
98     str     r1, [r0, #0]            // Store 1st read value to array
99     str     r2, [r0, #4]            // Store 2nd read value to array
100     str     r3, [r0, #8]            // Store 3rd read value to array
101     bx      lr                      // Return to caller
102 }
103 #elif (defined (__ARMCC_VERSION)) && (__ARMCC_VERSION >= 6000000)
104 void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])105 am_hal_triple_read(uint32_t ui32TimerAddr, uint32_t ui32Data[])
106 {
107   __asm (
108     " push  {R1, R4}\n"
109     " mrs   R4, PRIMASK\n"
110     " cpsid i\n"
111     " nop\n"
112     " ldr   R1, [R0, #0]\n"
113     " ldr   R2, [R0, #0]\n"
114     " ldr   R3, [R0, #0]\n"
115     " msr   PRIMASK, r4\n"
116     " pop   {R0, R4}\n"
117     " str   R1, [R0, #0]\n"
118     " str   R2, [R0, #4]\n"
119     " str   R3, [R0, #8]\n"
120     :
121     : [ui32TimerAddr] "r" (ui32TimerAddr),
122       [ui32Data] "r" (&ui32Data[0])
123     : "r0", "r1", "r2", "r3", "r4"
124   );
125 }
126 #elif defined(__GNUC_STDC_INLINE__)
127 __attribute__((naked))
128 void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])129 am_hal_triple_read(uint32_t ui32TimerAddr, uint32_t ui32Data[])
130 {
131     __asm
132     (
133         "   push    {r1, r4}\n"                 // Save r1=ui32Data, r4
134         "   mrs     r4, PRIMASK \n"             // Save current interrupt state
135         "   cpsid   i           \n"             // Disable INTs while reading the reg
136         "   ldr     r1, [r0, #0]\n"             // Read the designated register 3 times
137         "   ldr     r2, [r0, #0]\n"             //  "
138         "   ldr     r3, [r0, #0]\n"             //  "
139         "   msr     PRIMASK, r4 \n"             // Restore interrupt state
140         "   pop     {r0, r4}\n"                 // Get r0=ui32Data, restore r4
141         "   str     r1, [r0, #0]\n"             // Store 1st read value to array
142         "   str     r2, [r0, #4]\n"             // Store 2nd read value to array
143         "   str     r3, [r0, #8]\n"             // Store 3rd read value to array
144         "   bx      lr          \n"             // Return to caller
145     );
146 }
147 #elif defined(__IAR_SYSTEMS_ICC__)
148 #pragma diag_suppress = Pe940   // Suppress IAR compiler warning about missing
149                                 // return statement on a non-void function
150 __stackless void
am_hal_triple_read(uint32_t ui32TimerAddr,uint32_t ui32Data[])151 am_hal_triple_read( uint32_t ui32TimerAddr, uint32_t ui32Data[])
152 {
153     __asm(" push    {r1, r4}    ");         // Save r1=ui32Data, r4
154     __asm(" mrs     r4, PRIMASK ");         // Save current interrupt state
155     __asm(" cpsid   i           ");         // Disable INTs while reading the reg
156     __asm(" ldr     r1, [r0, #0]");         // Read the designated register 3 times
157     __asm(" ldr     r2, [r0, #0]");         //  "
158     __asm(" ldr     r3, [r0, #0]");         //  "
159     __asm(" msr     PRIMASK, r4 ");         // Restore interrupt state
160     __asm(" pop     {r0, r4}    ");         // Get r0=ui32Data, restore r4
161     __asm(" str     r1, [r0, #0]");         // Store 1st read value to array
162     __asm(" str     r2, [r0, #4]");         // Store 2nd read value to array
163     __asm(" str     r3, [r0, #8]");         // Store 3rd read value to array
164     __asm(" bx      lr          ");         // Return to caller
165 }
166 #pragma diag_default = Pe940    // Restore IAR compiler warning
167 #else
168 #error Compiler is unknown, please contact Ambiq support team
169 #endif
170 //*****************************************************************************
171 //
172 // End Doxygen group.
173 //! @}
174 //
175 //*****************************************************************************
176