1 /* 2 * Copyright (c) 2024 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @file 9 * @brief Buffers for USB device support 10 */ 11 12 #ifndef ZEPHYR_INCLUDE_UDC_BUF_H 13 #define ZEPHYR_INCLUDE_UDC_BUF_H 14 15 #include <zephyr/kernel.h> 16 #include <zephyr/net/buf.h> 17 18 #if defined(CONFIG_DCACHE) && !defined(CONFIG_UDC_BUF_FORCE_NOCACHE) 19 /* 20 * Here we try to get DMA-safe buffers, but we lack a consistent source of 21 * information about data cache properties, such as line cache size, and a 22 * consistent source of information about what part of memory is DMA'able. 23 * For now, we simply assume that all available memory is DMA'able and use 24 * Kconfig option DCACHE_LINE_SIZE for alignment and granularity. 25 */ 26 #define Z_UDC_BUF_ALIGN CONFIG_DCACHE_LINE_SIZE 27 #define Z_UDC_BUF_GRANULARITY CONFIG_DCACHE_LINE_SIZE 28 #else 29 /* 30 * Default alignment and granularity to pointer size if the platform does not 31 * have a data cache or buffers are placed in nocache memory region. 32 */ 33 #define Z_UDC_BUF_ALIGN sizeof(void *) 34 #define Z_UDC_BUF_GRANULARITY sizeof(void *) 35 #endif 36 37 /** 38 * @brief Buffer macros and definitions used in USB device support 39 * @defgroup udc_buf Buffer macros and definitions used in USB device support 40 * @ingroup usb 41 * @{ 42 */ 43 44 /** Buffer alignment required by the UDC driver */ 45 #define UDC_BUF_ALIGN Z_UDC_BUF_ALIGN 46 47 /** Buffer granularity required by the UDC driver */ 48 #define UDC_BUF_GRANULARITY Z_UDC_BUF_GRANULARITY 49 50 /** 51 * @brief Define a UDC driver-compliant static buffer 52 * 53 * This macro should be used if the application defines its own buffers to be 54 * used for USB transfers. 55 * 56 * @param name Buffer name 57 * @param size Buffer size 58 */ 59 #define UDC_STATIC_BUF_DEFINE(name, size) \ 60 static uint8_t __aligned(UDC_BUF_ALIGN) name[ROUND_UP(size, UDC_BUF_GRANULARITY)]; 61 62 /** 63 * @brief Verify that the buffer is aligned as required by the UDC driver 64 * 65 * @see IS_ALIGNED 66 * 67 * @param buf Buffer pointer 68 */ 69 #define IS_UDC_ALIGNED(buf) IS_ALIGNED(buf, UDC_BUF_ALIGN) 70 71 /** 72 * @cond INTERNAL_HIDDEN 73 */ 74 #define UDC_HEAP_DEFINE(name, bytes, in_section) \ 75 uint8_t in_section __aligned(UDC_BUF_ALIGN) \ 76 kheap_##name[MAX(bytes, Z_HEAP_MIN_SIZE)]; \ 77 STRUCT_SECTION_ITERABLE(k_heap, name) = { \ 78 .heap = { \ 79 .init_mem = kheap_##name, \ 80 .init_bytes = MAX(bytes, Z_HEAP_MIN_SIZE), \ 81 }, \ 82 } 83 84 #define UDC_K_HEAP_DEFINE(name, size) \ 85 COND_CODE_1(CONFIG_UDC_BUF_FORCE_NOCACHE, \ 86 (UDC_HEAP_DEFINE(name, size, __nocache)), \ 87 (UDC_HEAP_DEFINE(name, size, __noinit))) 88 89 extern const struct net_buf_data_cb net_buf_dma_cb; 90 /** @endcond */ 91 92 /** 93 * @brief Define a new pool for UDC buffers with variable-size payloads 94 * 95 * This macro is similar to `NET_BUF_POOL_VAR_DEFINE`, but provides buffers 96 * with alignment and granularity suitable for use by UDC driver. 97 * 98 * @see NET_BUF_POOL_VAR_DEFINE 99 * 100 * @param pname Name of the pool variable. 101 * @param count Number of buffers in the pool. 102 * @param size Maximum data payload per buffer. 103 * @param ud_size User data space to reserve per buffer. 104 * @param fdestroy Optional destroy callback when buffer is freed. 105 */ 106 #define UDC_BUF_POOL_VAR_DEFINE(pname, count, size, ud_size, fdestroy) \ 107 _NET_BUF_ARRAY_DEFINE(pname, count, ud_size); \ 108 UDC_K_HEAP_DEFINE(net_buf_mem_pool_##pname, size); \ 109 static const struct net_buf_data_alloc net_buf_data_alloc_##pname = { \ 110 .cb = &net_buf_dma_cb, \ 111 .alloc_data = &net_buf_mem_pool_##pname, \ 112 .max_alloc_size = 0, \ 113 }; \ 114 static STRUCT_SECTION_ITERABLE(net_buf_pool, pname) = \ 115 NET_BUF_POOL_INITIALIZER(pname, &net_buf_data_alloc_##pname, \ 116 _net_buf_##pname, count, ud_size, \ 117 fdestroy) 118 119 /** 120 * @brief Define a new pool for UDC buffers based on fixed-size data 121 * 122 * This macro is similar to `NET_BUF_POOL_DEFINE`, but provides buffers 123 * with alignment and granularity suitable for use by UDC driver. 124 * 125 * @see NET_BUF_POOL_DEFINE 126 127 * @param pname Name of the pool variable. 128 * @param count Number of buffers in the pool. 129 * @param size Maximum data payload per buffer. 130 * @param ud_size User data space to reserve per buffer. 131 * @param fdestroy Optional destroy callback when buffer is freed. 132 */ 133 #define UDC_BUF_POOL_DEFINE(pname, count, size, ud_size, fdestroy) \ 134 _NET_BUF_ARRAY_DEFINE(pname, count, ud_size); \ 135 static uint8_t __nocache __aligned(UDC_BUF_ALIGN) \ 136 net_buf_data_##pname[count][size]; \ 137 static const struct net_buf_pool_fixed net_buf_fixed_##pname = { \ 138 .data_pool = (uint8_t *)net_buf_data_##pname, \ 139 }; \ 140 static const struct net_buf_data_alloc net_buf_fixed_alloc_##pname = { \ 141 .cb = &net_buf_fixed_cb, \ 142 .alloc_data = (void *)&net_buf_fixed_##pname, \ 143 .max_alloc_size = size, \ 144 }; \ 145 static STRUCT_SECTION_ITERABLE(net_buf_pool, pname) = \ 146 NET_BUF_POOL_INITIALIZER(pname, &net_buf_fixed_alloc_##pname, \ 147 _net_buf_##pname, count, ud_size, \ 148 fdestroy) 149 150 /** 151 * @} 152 */ 153 154 #endif /* ZEPHYR_INCLUDE_UDC_BUF_H */ 155