1 /*
2  *-------------------------------------------------------------------------------
3  * \file cy_syslib_iar.c
4  * \version 2.20
5  *
6  *  \brief Assembly routines for IAR.
7  *
8  *-------------------------------------------------------------------------------
9  * Copyright 2016-2020 Cypress Semiconductor Corporation
10  * SPDX-License-Identifier: Apache-2.0
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *     http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  *
24  * Derived from ../armclang/cy_syslib_mdk.s
25  */
26 
27 #include "system_psoc6.h"
28 
29 /*
30  *-------------------------------------------------------------------------------
31  * Function Name: Cy_SysLib_DelayCycles
32  *-------------------------------------------------------------------------------
33  *
34  * Summary:
35  *  Delays for the specified number of cycles.
36  *
37  * Parameters:
38  *  uint32_t cycles: The number of cycles to delay.
39  *
40  *-------------------------------------------------------------------------------
41  */
42 
Cy_SysLib_DelayCycles(uint32_t cycles)43 void Cy_SysLib_DelayCycles(uint32_t cycles)
44 {
45 asm("ADDS %0, %0, #2         ;    1    2    Round to the nearest multiple of 4. \n"
46     "LSRS %0, %0, #2         ;    1    2    Divide by 4 and set flags.          \n"
47     "BEQ Cy_DelayCycles_done ;    2    2    Skip if 0.                          \n"
48 "Cy_DelayCycles_loop:                                                           \n"
49     "ADDS %0, %0, #1         ;    1    2    Increment the counter.              \n"
50     "SUBS %0, %0, #2         ;    1    2    Decrement the counter by 2.         \n"
51     "BNE Cy_DelayCycles_loop ;   (1)2  2    2 CPU cycles (if branch is taken).  \n"
52     "NOP                     ;    1    2    Loop alignment padding.             \n"
53 "Cy_DelayCycles_done:                                                           \n"
54     ";BX lr                   ;    3    2                                        \n"
55     :
56     : "r" (cycles));
57 }
58 
59 
60 /*
61  *-------------------------------------------------------------------------------
62  * Function Name: Cy_SysLib_EnterCriticalSection
63  *-------------------------------------------------------------------------------
64  *
65  * Summary:
66  *  Cy_SysLib_EnterCriticalSection disables interrupts and returns a value
67  *  indicating whether interrupts were previously enabled.
68  *
69  *  Note Implementation of Cy_SysLib_EnterCriticalSection manipulates the IRQ
70  *  enable bit with interrupts still enabled. The test and set of the interrupt
71  *  bits are not atomic. Therefore, to avoid a corrupting processor state, it must
72  *  be the policy that all interrupt routines restore the interrupt enable bits as
73  *  they were found on entry.
74  *
75  * Return:
76  *  uint8_t
77  *   Returns 0 if interrupts were previously enabled or 1 if interrupts
78  *   were previously disabled.
79  *
80  *-------------------------------------------------------------------------------
81  */
82 
Cy_SysLib_EnterCriticalSection(void)83 uint8_t Cy_SysLib_EnterCriticalSection(void)
84 {
85     uint8_t mask;
86 asm("MRS %0, PRIMASK         ; Save and return an interrupt state. \n"
87     "CPSID I                 ; Disable the interrupts.             \n"
88     : "=r" (mask)
89     :);
90     return mask;
91 }
92 
93 /*
94  *-------------------------------------------------------------------------------
95  * Function Name: Cy_SysLib_ExitCriticalSection
96  *-------------------------------------------------------------------------------
97  *
98  * Summary:
99  *  Cy_SysLib_ExitCriticalSection re-enables interrupts if they were enabled
100  *  before Cy_SysLib_EnterCriticalSection was called. The argument should be the
101  *  value returned from Cy_SysLib_EnterCriticalSection.
102  *
103  * Parameters:
104  *  uint8_t savedIntrStatus:
105  *   The saved interrupt status returned by the Cy_SysLib_EnterCriticalSection
106  *   function.
107  *
108  *-------------------------------------------------------------------------------
109  */
110 
Cy_SysLib_ExitCriticalSection(uint8_t savedIntrStatus)111 void Cy_SysLib_ExitCriticalSection(uint8_t savedIntrStatus)
112 {
113 asm("MSR PRIMASK, %0         ; Restore the interrupt state. \n"
114     :
115     : "r" (savedIntrStatus)
116     );
117 }
118