1 /***************************************************************************//** 2 * \file cyhal_ipc_impl.h 3 * 4 * \brief 5 * CAT1 specific implementation for IPC API. 6 * 7 ******************************************************************************** 8 * \copyright 9 * Copyright 2019-2021 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 #pragma once 28 29 #if (CYHAL_DRIVER_AVAILABLE_IPC) 30 31 #if defined(__cplusplus) 32 extern "C" { 33 #endif /* __cplusplus */ 34 35 /** 36 * \addtogroup group_hal_impl_ipc IPC 37 * \ingroup group_hal_impl 38 * \{ 39 * Implementation specific interface for using the IPC driver. 40 * 41 */ 42 43 /** 44 * \cond INTERNAL 45 */ 46 47 #if defined(COMPONENT_CAT1A) 48 /* On CAT1A devices CY_IPC_CHANNELS is not available at compile time, 49 except for TVIIBE devices. */ 50 #if defined (CPUSS_IPC_IPC_NR) && (CPUSS_IPC_IPC_NR > 0) 51 #define _CYHAL_IPC_DRV_CHANNELS (CPUSS_IPC_IPC_NR) 52 #else 53 #define _CYHAL_IPC_DRV_CHANNELS (16u) 54 #endif 55 #elif defined(COMPONENT_CAT1D) 56 /* Last channel is used by semaphores */ 57 #define _CYHAL_IPC_DRV_CHANNELS (CY_IPC_IP1_CH - 1) 58 #else 59 #define _CYHAL_IPC_DRV_CHANNELS (CPUSS_IPC_IPC_NR) 60 #endif 61 62 /** Definition of _CYHAL_IPC_CHAN_USER which stands for first user-available IPC channel index */ 63 #if defined(CY_IPC_CHAN_USER) 64 #if defined(COMPONENT_CAT1D) 65 #define _CYHAL_IPC_CHAN_USER (CY_IPC_CHAN_USER - IPC0_IPC_NR) 66 #else 67 #define _CYHAL_IPC_CHAN_USER (CY_IPC_CHAN_USER) 68 #endif 69 #else 70 #if defined(COMPONENT_CAT1A) 71 #define _CYHAL_IPC_CHAN_USER (CY_IPC_CHAN_DDFT + 1) 72 #elif defined(COMPONENT_CAT1B) 73 #define _CYHAL_IPC_CHAN_USER (0u) 74 #else 75 #error "Unhandled device" 76 #endif /* defined(COMPONENT_CAT1A) or defined(COMPONENT_CAT1B) or other */ 77 #endif /* !defined(CY_IPC_CHAN_USER) */ 78 79 /** Number of available for IPC HAL user channels */ 80 #define CYHAL_IPC_USR_CHANNELS ((_CYHAL_IPC_DRV_CHANNELS) - _CYHAL_IPC_CHAN_USER) 81 82 #if (CYHAL_IPC_USR_CHANNELS > 0) 83 /** User IPC channel 0 */ 84 #define CYHAL_IPC_CHAN_0 (_CYHAL_IPC_CHAN_USER) 85 #endif /* CYHAL_IPC_USR_CHANNELS > 0 */ 86 #if (CYHAL_IPC_USR_CHANNELS > 1) 87 /** User IPC channel 1 */ 88 #define CYHAL_IPC_CHAN_1 (_CYHAL_IPC_CHAN_USER + 1) 89 #endif /* CYHAL_IPC_USR_CHANNELS > 1 */ 90 #if (CYHAL_IPC_USR_CHANNELS > 2) 91 /** User IPC channel 2 */ 92 #define CYHAL_IPC_CHAN_2 (_CYHAL_IPC_CHAN_USER + 2) 93 #endif /* CYHAL_IPC_USR_CHANNELS > 2 */ 94 #if (CYHAL_IPC_USR_CHANNELS > 3) 95 /** User IPC channel 3 */ 96 #define CYHAL_IPC_CHAN_3 (_CYHAL_IPC_CHAN_USER + 3) 97 #endif /* CYHAL_IPC_USR_CHANNELS > 3 */ 98 #if (CYHAL_IPC_USR_CHANNELS > 4) 99 /** User IPC channel 4 */ 100 #define CYHAL_IPC_CHAN_4 (_CYHAL_IPC_CHAN_USER + 4) 101 #endif /* CYHAL_IPC_USR_CHANNELS > 4 */ 102 #if (CYHAL_IPC_USR_CHANNELS > 5) 103 /** User IPC channel 5 */ 104 #define CYHAL_IPC_CHAN_5 (_CYHAL_IPC_CHAN_USER + 5) 105 #endif /* CYHAL_IPC_USR_CHANNELS > 5 */ 106 #if (CYHAL_IPC_USR_CHANNELS > 6) 107 /** User IPC channel 6 */ 108 #define CYHAL_IPC_CHAN_6 (_CYHAL_IPC_CHAN_USER + 6) 109 #endif /* CYHAL_IPC_USR_CHANNELS > 6 */ 110 #if (CYHAL_IPC_USR_CHANNELS > 7) 111 /** User IPC channel 7 */ 112 #define CYHAL_IPC_CHAN_7 (_CYHAL_IPC_CHAN_USER + 7) 113 #endif /* CYHAL_IPC_USR_CHANNELS > 7 */ 114 #if (CYHAL_IPC_USR_CHANNELS > 8) 115 /** User IPC channel 8 */ 116 #define CYHAL_IPC_CHAN_8 (_CYHAL_IPC_CHAN_USER + 8) 117 #endif /* CYHAL_IPC_USR_CHANNELS > 8 */ 118 #if (CYHAL_IPC_USR_CHANNELS > 9) 119 /** User IPC channel 9 */ 120 #define CYHAL_IPC_CHAN_9 (_CYHAL_IPC_CHAN_USER + 9) 121 #endif /* CYHAL_IPC_USR_CHANNELS > 9 */ 122 #if (CYHAL_IPC_USR_CHANNELS > 10) 123 /** User IPC channel 10 */ 124 #define CYHAL_IPC_CHAN_10 (_CYHAL_IPC_CHAN_USER + 10) 125 #endif /* CYHAL_IPC_USR_CHANNELS > 10 */ 126 #if (CYHAL_IPC_USR_CHANNELS > 11) 127 /** User IPC channel 11 */ 128 #define CYHAL_IPC_CHAN_11 (_CYHAL_IPC_CHAN_USER + 11) 129 #endif /* CYHAL_IPC_USR_CHANNELS > 11 */ 130 #if (CYHAL_IPC_USR_CHANNELS > 12) 131 /** User IPC channel 12 */ 132 #define CYHAL_IPC_CHAN_12 (_CYHAL_IPC_CHAN_USER + 12) 133 #endif /* CYHAL_IPC_USR_CHANNELS > 12 */ 134 #if (CYHAL_IPC_USR_CHANNELS > 13) 135 /** User IPC channel 13 */ 136 #define CYHAL_IPC_CHAN_13 (_CYHAL_IPC_CHAN_USER + 13) 137 #endif /* CYHAL_IPC_USR_CHANNELS > 13 */ 138 #if (CYHAL_IPC_USR_CHANNELS > 14) 139 /** User IPC channel 14 */ 140 #define CYHAL_IPC_CHAN_14 (_CYHAL_IPC_CHAN_USER + 14) 141 #endif /* CYHAL_IPC_USR_CHANNELS > 14 */ 142 #if (CYHAL_IPC_USR_CHANNELS > 15) 143 /** User IPC channel 15 */ 144 #define CYHAL_IPC_CHAN_15 (_CYHAL_IPC_CHAN_USER + 15) 145 #endif /* CYHAL_IPC_USR_CHANNELS > 15 */ 146 #if (CYHAL_IPC_USR_CHANNELS > 16) 147 #error "Unhandled number of free IPC channels" 148 #endif /* CYHAL_IPC_USR_CHANNELS > 16 */ 149 150 /** Definition of _CYHAL_IPC_INTR_USER which stands for first user-available IPC interrupt structure index */ 151 #if defined(CY_IPC_INTR_USER) 152 #if defined(COMPONENT_CAT1D) 153 #define _CYHAL_IPC_INTR_USER (CY_IPC_INTR_USER - IPC0_IPC_IRQ_NR) 154 #else 155 #define _CYHAL_IPC_INTR_USER (CY_IPC_INTR_USER) 156 #endif 157 #elif defined(CY_IPC_INTR_SPARE) 158 #define _CYHAL_IPC_INTR_USER (CY_IPC_INTR_SPARE) 159 #else 160 #define _CYHAL_IPC_INTR_USER (CYHAL_IPC_CHAN_0) 161 #endif 162 163 #define _CYHAL_IPC_CHAN_IDX_CORRECT(channel) (((channel) >= CYHAL_IPC_CHAN_0) && ((channel) < (CYHAL_IPC_CHAN_0 + CYHAL_IPC_USR_CHANNELS))) 164 165 #ifdef CPUSS_IPC_IPC_IRQ_NR 166 #define _CYHAL_IPC_RELEASE_INTR_BITS (CPUSS_IPC_IPC_IRQ_NR) 167 #else 168 #define _CYHAL_IPC_RELEASE_INTR_BITS (16u) 169 #endif 170 171 #ifdef CY_IPC_CHAN_SEMA 172 #define _CYHAL_IPC_PDL_SEMA_CHAN (CY_IPC_CHAN_SEMA) 173 #elif defined(COMPONENT_CAT1D) 174 /* Last available channel is used for semaphores */ 175 #define _CYHAL_IPC_PDL_SEMA_CHAN (CY_IPC_IP1_CH - 1) 176 #endif /* ifdef CY_IPC_CHAN_SEMA or other */ 177 178 /** \endcond */ 179 180 /** Number of semaphores, that can be used */ 181 #ifdef CY_IPC_SEMA_COUNT 182 #define CYHAL_IPC_SEMA_COUNT (CY_IPC_SEMA_COUNT) 183 #else 184 #define CYHAL_IPC_SEMA_COUNT (128u) 185 #endif /* ifdef CY_IPC_SEMA_COUNT or other */ 186 187 /** The round up of cacheline size MACRO */ 188 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) 189 #define L1_DCACHE_LINE_BYTES_MASK (uint32_t)(__SCB_DCACHE_LINE_SIZE - 1) 190 #define L1_DCACHE_ROUND_UP_BYTES(a) (((uint32_t)(a) + L1_DCACHE_LINE_BYTES_MASK) & ~(L1_DCACHE_LINE_BYTES_MASK)) 191 #define L1_DCACHE_LINE_WORDS_MASK (uint32_t)((__SCB_DCACHE_LINE_SIZE >> 2) - 1) 192 #define L1_DCACHE_ROUND_UP_WORDS(a) (((uint32_t)(a) + L1_DCACHE_LINE_WORDS_MASK) & ~(L1_DCACHE_LINE_WORDS_MASK)) 193 #endif /* defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) */ 194 195 /** Macro for Queue pool shared memory allocation. Can be used only in function scope. Please use CY_SECTION_SHAREDMEM 196 * instead if allocation in global scope is needed. 197 * Params: 198 * queue_pool - void pointer to point to the shared memory 199 * NUM_ITEMS - number of items, that are expected to fit into the queue 200 * ITEMSIZE - size of one queue item (in bytes) 201 */ 202 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) 203 #define CYHAL_IPC_QUEUE_POOL_ALLOC(queue_pool, NUM_ITEMS, ITEMSIZE) \ 204 do { \ 205 CY_SECTION_SHAREDMEM static uint8_t _cyhal_ipc_queue_pool[L1_DCACHE_ROUND_UP_BYTES(ITEMSIZE * NUM_ITEMS)] CY_ALIGN(__SCB_DCACHE_LINE_SIZE); \ 206 queue_pool = (void*)&_cyhal_ipc_queue_pool; \ 207 } while (0) 208 #else 209 #define CYHAL_IPC_QUEUE_POOL_ALLOC(queue_pool, NUM_ITEMS, ITEMSIZE) \ 210 do { \ 211 CY_SECTION_SHAREDMEM static uint8_t _cyhal_ipc_queue_pool[ITEMSIZE * NUM_ITEMS]; \ 212 queue_pool = (void*)&_cyhal_ipc_queue_pool; \ 213 } while (0) 214 #endif /* defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) */ 215 216 /** Macro for Queue handle shared memory allocation. Can be used only in function scope. Please use CY_SECTION_SHAREDMEM 217 * instead if allocation in global scope is needed. 218 * Params: 219 * queue_handle - pointer to cyhal_ipc_queue_t data type, which will point to the shared memory 220 */ 221 #if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) 222 #define CYHAL_IPC_QUEUE_HANDLE_ALLOC(queue_handle) \ 223 do { \ 224 CY_SECTION_SHAREDMEM static cyhal_ipc_queue_t _cyhal_ipc_queue_handle CY_ALIGN(__SCB_DCACHE_LINE_SIZE); \ 225 queue_handle = &_cyhal_ipc_queue_handle; \ 226 } while (0) 227 #else 228 #define CYHAL_IPC_QUEUE_HANDLE_ALLOC(queue_handle) \ 229 do { \ 230 CY_SECTION_SHAREDMEM static cyhal_ipc_queue_t _cyhal_ipc_queue_handle; \ 231 queue_handle = &_cyhal_ipc_queue_handle; \ 232 } while (0) 233 #endif /* defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) */ 234 235 /** Polling interval, that will be used in blocking cyhal_ipc_* functions. 236 * It is recommended to use value either below 1000 (e.g. 750) or multiple of 1000 (e.g. 1000, 2000, 3000, etc.) 237 */ 238 #ifndef CYHAL_IPC_POLLING_INTERVAL_uS 239 #define CYHAL_IPC_POLLING_INTERVAL_uS (1000u) 240 #endif /* #ifndef CYHAL_IPC_POLLING_INTERVAL_uS */ 241 242 /** This macro defines what device's core will initialize IPC PDL semaphores in scope of cyhal_ipc_semaphore_init call. 243 * Please refer to implementation specific documentation for details. 244 */ 245 #ifndef CYHAL_IPC_INIT_CORE 246 #if defined(CY_DEVICE_TVIIBE) 247 #define CYHAL_IPC_INIT_CORE CORE_NAME_CM4_0 248 #elif defined(COMPONENT_CAT1C) 249 #define CYHAL_IPC_INIT_CORE CORE_NAME_CM7_0 250 #elif defined(COMPONENT_CAT1D) 251 #define CYHAL_IPC_INIT_CORE CORE_NAME_CM55 252 #endif /* defined(COMPONENT_CAT1C) or defined(COMPONENT_CAT1D) */ 253 #endif /* not defined (CYHAL_IPC_INIT_CORE) */ 254 255 /** Number of RTOS semaphores, that will be allocated and used by driver in RTOS environment 256 * (CY_RTOS_AWARE or COMPONENT_RTOS_AWARE should be defined). Usage of RTOS semaphores in IPC semaphores implementation 257 * helps to utilize waiting for semaphores times in RTOS environment more effectively. To achieve most effectiveness, 258 * it is recommended to define CYHAL_IPC_RTOS_SEMA_NUM value to be greater-equal to the number of IPC semaphores, that 259 * are planned to be used. Only semaphores with `semaphore_num`, that is less than _CYHAL_IPC_RELEASE_INTR_BITS can 260 * benefit from this feature. 261 * Value of this define can be 0. In this case, IPC HAL semaphores will not use RTOS semaphores.*/ 262 #ifndef CYHAL_IPC_RTOS_SEMA_NUM 263 #define CYHAL_IPC_RTOS_SEMA_NUM (4u) 264 #endif /* #ifndef CYHAL_IPC_RTOS_SEMA_NUM */ 265 266 #if (CYHAL_IPC_RTOS_SEMA_NUM > _CYHAL_IPC_RELEASE_INTR_BITS) 267 #error "Cannot handle selected amount of RTOS semaphores. Please fix CYHAL_IPC_RTOS_SEMA_NUM value" 268 #endif /* CYHAL_IPC_RTOS_SEMA_NUM > _CYHAL_IPC_RELEASE_INTR_BITS */ 269 270 /** \} group_hal_impl_ipc */ 271 272 #if defined(__cplusplus) 273 } 274 #endif /* __cplusplus */ 275 276 #endif /* CYHAL_DRIVER_AVAILABLE_IPC */ 277