1 /***************************************************************************//**
2 * \file cyhal_utils.h
3 *
4 * \brief
5 * Provides utility functions.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation
11 *
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26
27 /** \cond INTERNAL */
28 /**
29 * \addtogroup group_hal_impl
30 * \{
31 * Common utility macros & functions used by multiple HAL drivers.
32 */
33
34 #pragma once
35
36 #include "cy_result.h"
37 #include "cyhal_hw_types.h"
38 #include "cy_utils.h"
39 #if !defined(COMPONENT_CAT4)
40 #include "cyhal_utils_impl.h"
41 #endif
42
43 #if defined(__cplusplus)
44 extern "C" {
45 #endif
46
47 #define _CYHAL_UTILS_NS_PER_SECOND (1000000000)
48 #define _CYHAL_UTILS_US_PER_MS (1000)
49 #define _CYHAL_UTILS_ONE_TIME_UNIT (1) /**< Used to do a delay in one time unit (1 ms, 1 us) */
50
51 #define _CYHAL_UTILS_IRQN_OFFSET (16U) /**< Offset for implementation-defined ISR type numbers (IRQ0 = 16) */
52 #define _CYHAL_UTILS_GET_CURRENT_IRQN() ((IRQn_Type) (__get_IPSR() - _CYHAL_UTILS_IRQN_OFFSET)) /**< Macro to get the IRQn of the current ISR */
53
54 /** Assigns the specified resource with the provided type, block_num, and channel_num
55 */
56 #define _CYHAL_UTILS_ASSIGN_RESOURCE(rsc, resource_type, map) \
57 (rsc).type = (resource_type); \
58 (rsc).block_num = ((map)->block_num); \
59 (rsc).channel_num = ((map)->channel_num)
60
61 /**
62 * \addtogroup group_hal_impl_pin_package
63 * \{
64 */
65
66 /** Attempts to reserve a resource block that connects to the specified pin from the provided resource pin mapping table.
67 * If the first matching block cannot be reserved, this will continue searching until either a match is successfully
68 * reserved or the end of the table is reached.
69 * This is a convenience utility for _cyhal_utils_get_resource() if the mappings is an array of known size.
70 *
71 * @param[in] pin The pin to which the reserved hardware block must connect
72 * @param[in] rsc The type of hardware resource being allocated
73 * @param[in] mappings The mapping of pin to hardware block
74 * @return The entry for the specified pin corresponding to the reserved block, if it exists and was successfully reserved.
75 Otherwise, NULL.
76 */
77 #define _CYHAL_UTILS_TRY_ALLOC(pin, rsc, mappings) \
78 _cyhal_utils_try_alloc(pin, rsc, mappings, sizeof(mappings)/sizeof(cyhal_resource_pin_mapping_t))
79
80 /** Looks up the resource block that connects to the specified pins from the provided resource pin mapping table.
81 * This is a convenience utility for _cyhal_utils_get_resource() if the mappings is an array of known size.
82 *
83 * @param[in] pin The pin to lookup the hardware block for
84 * @param[in] mappings The mappings of pin to hardware block
85 * @return The entry for the specified pin if it exists, or null if it doesn't.
86 */
87 #define _CYHAL_UTILS_GET_RESOURCE(pin, mappings) _cyhal_utils_get_resource(pin, mappings, sizeof(mappings)/sizeof(cyhal_resource_pin_mapping_t), NULL, false)
88
89 /** Looks up the resource block that connects to the specified pins from the provided resource pin mapping table.
90 * This is a convenience utility for _cyhal_utils_get_resource() if the mappings is an array of known size.
91 *
92 * @param[in] pin The pin to lookup the hardware block for
93 * @param[in] mappings The mappings of pin to hardware block
94 * @param[in] block_res If not NULL, find pin mapping, that belongs to specified block
95 * @return The entry for the specified pin if it exists, or null if it doesn't.
96 */
97 #define _CYHAL_UTILS_GET_RESOURCE_INST(pin, mappings, block_res) _cyhal_utils_get_resource(pin, mappings, sizeof(mappings)/sizeof(cyhal_resource_pin_mapping_t), (block_res), false)
98
99 /** Looks up the resource block that connects to the specified pins from the provided resource pin mapping table.
100 *
101 * @param[in] pin The pin to lookup the hardware block for
102 * @param[in] mappings The mappings of pin to hardware block
103 * @param[in] count The number of items in the mappings table
104 * @param[in] block_res If not NULL, find pin mapping, that belongs to specified block
105 * @param[in] ignore_channel Ignore channel differences
106 * @return The entry for the specified pin if it exists, or null if it doesn't.
107 */
108 const cyhal_resource_pin_mapping_t *_cyhal_utils_get_resource(cyhal_gpio_t pin, const cyhal_resource_pin_mapping_t* mappings, size_t count, const cyhal_resource_inst_t* block_res, bool ignore_channel);
109
110 /** Attempts to reserve a resource block that connects to the specified pin from the provided resource pin mapping table.
111 * If the first matching block cannot be reserved, this will continue searching until either a match is successfully
112 * reserved or the end of the table is reached.
113 *
114 * @param[in] pin The pin to which the reserved hardware block must connect
115 * @param[in] rsc The type of hardware resource being allocated
116 * @param[in] pin_map The mapping of pin to hardware block
117 * @param[in] size The number of items in the mappings table
118 * @return The entry for the specified pin corresponding to the reserved block, if it exists and was successfully reserved.
119 Otherwise, NULL.
120 */
121 const cyhal_resource_pin_mapping_t* _cyhal_utils_try_alloc(cyhal_gpio_t pin, cyhal_resource_t rsc, const cyhal_resource_pin_mapping_t *pin_map, size_t count);
122
123 /** Checks to see if the provided pin is a no-connect (CYHAL_NC_PIN_VALUE). If not, calls
124 * _cyhal_utils_disconnect_and_free().
125 *
126 * @param[in] pin The pin to disconnect and free
127 */
128 void _cyhal_utils_release_if_used(cyhal_gpio_t *pin);
129
130 /** Determine if the two resource instances reference the same item.
131 *
132 * @param[in] resource1 The first resource instance to compare
133 * @param[in] resource2 The second resource instance to compare
134 * @return Boolean indicating whether two resources are the same
135 */
_cyhal_utils_resources_equal(const cyhal_resource_inst_t * resource1,const cyhal_resource_inst_t * resource2)136 static inline bool _cyhal_utils_resources_equal(const cyhal_resource_inst_t *resource1, const cyhal_resource_inst_t *resource2)
137 {
138 return (resource1->type == resource2->type) && (resource1->block_num == resource2->block_num) && (resource1->channel_num == resource2->channel_num);
139 }
140
141 /** Determine if the block and channel are the same for the provided resource instance and pin map instance.
142 *
143 * @param[in] resource The resource instance to compare
144 * @param[in] map The pin map instance to compare
145 * @param[in] ignore_channel Ignore channel differences
146 * @return Boolean indicating whether two resources are the same
147 */
_cyhal_utils_map_resource_equal(const cyhal_resource_inst_t * resource,const cyhal_resource_pin_mapping_t * map,bool ignore_channel)148 static inline bool _cyhal_utils_map_resource_equal(const cyhal_resource_inst_t *resource, const cyhal_resource_pin_mapping_t *map,
149 bool ignore_channel)
150 {
151 return (resource->block_num == map->block_num) && (ignore_channel || resource->channel_num == map->channel_num);
152 }
153
154 /** Determine if two pin map resources are the same. If more than two instances need to be
155 * compared, it is better to call \ref _cyhal_utils_map_resources_equal_all().
156 *
157 * @param[in] map1 First pin map resource to compare
158 * @param[in] map2 Second pin map resource to compare
159 * @return Boolean indicating whether two resources are the same
160 */
_cyhal_utils_map_resources_equal(const cyhal_resource_pin_mapping_t * map1,const cyhal_resource_pin_mapping_t * map2)161 static inline bool _cyhal_utils_map_resources_equal(const cyhal_resource_pin_mapping_t *map1, const cyhal_resource_pin_mapping_t *map2)
162 {
163 return (map1->block_num == map2->block_num) && (map1->channel_num == map2->channel_num);
164 }
165
166 /** Determine if the set of pin map resources are the same. This expects at least two resource
167 * instances to be provided. NOTE: If only two instances are provided it is better
168 * to use \ref _cyhal_utils_map_resources_equal().
169 *
170 * @param[in] count The number of resources being provided to compare
171 * @param[in] ... Variable List of const cyhal_resource_inst_t* items to compare
172 * @return Boolean indicating whether resource instances are the same
173 */
174 bool _cyhal_utils_map_resources_equal_all(uint32_t count, ...);
175
176 /** Converts a set of flags from one representation to a equivalent set of flags
177 * in another representation.
178 * For example usage see cyhal_syspm.c or cyhal_sdhc.c
179 *
180 * @param[in] map New flag values. Each index corresponds to a bit position
181 * from the source_flags. Index 0 is a default value if nothing
182 * matches.
183 * @param[in] count Count of the total flags in the list.
184 * @param[in] source_flags Source flags to be converted.
185 * @return Converted flags.
186 */
187 uint32_t _cyhal_utils_convert_flags(const uint32_t map[], uint32_t count, uint32_t source_flags);
188
189 #if defined(__cplusplus)
190 }
191 #endif
192
193 /** \} group_hal_impl_utils */
194 /** \} group_hal_impl */
195 /** \endcond */
196