Line data Source code
1 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 : #if defined(CONFIG_UDC_BUF_FORCE_NOCACHE)
39 : /*
40 : * The usb transfer buffer needs to be in __nocache section
41 : */
42 : #define Z_UDC_BUF_SECTION __nocache
43 : #else
44 : #define Z_UDC_BUF_SECTION
45 : #endif
46 :
47 : /**
48 : * @brief Buffer macros and definitions used in USB device support
49 : * @defgroup udc_buf Buffer macros and definitions used in USB device support
50 : * @ingroup usb
51 : * @since 4.0
52 : * @version 0.1.0
53 : * @{
54 : */
55 :
56 : /** Buffer alignment required by the UDC driver */
57 1 : #define UDC_BUF_ALIGN Z_UDC_BUF_ALIGN
58 :
59 : /** Buffer granularity required by the UDC driver */
60 1 : #define UDC_BUF_GRANULARITY Z_UDC_BUF_GRANULARITY
61 :
62 : /**
63 : * @brief Define a UDC driver-compliant static buffer
64 : *
65 : * This macro should be used if the application defines its own buffers to be
66 : * used for USB transfers.
67 : *
68 : * @param name Buffer name
69 : * @param size Buffer size
70 : */
71 1 : #define UDC_STATIC_BUF_DEFINE(name, size) \
72 : static uint8_t Z_UDC_BUF_SECTION __aligned(UDC_BUF_ALIGN) \
73 : name[ROUND_UP(size, UDC_BUF_GRANULARITY)];
74 :
75 : /**
76 : * @brief Verify that the buffer is aligned as required by the UDC driver
77 : *
78 : * @see IS_ALIGNED
79 : *
80 : * @param buf Buffer pointer
81 : */
82 1 : #define IS_UDC_ALIGNED(buf) IS_ALIGNED(buf, UDC_BUF_ALIGN)
83 :
84 : /**
85 : * @cond INTERNAL_HIDDEN
86 : */
87 : #define UDC_HEAP_DEFINE(name, bytes, in_section) \
88 : uint8_t in_section __aligned(UDC_BUF_ALIGN) \
89 : kheap_##name[MAX(bytes, Z_HEAP_MIN_SIZE)]; \
90 : STRUCT_SECTION_ITERABLE(k_heap, name) = { \
91 : .heap = { \
92 : .init_mem = kheap_##name, \
93 : .init_bytes = MAX(bytes, Z_HEAP_MIN_SIZE), \
94 : }, \
95 : }
96 :
97 : #define UDC_K_HEAP_DEFINE(name, size) \
98 : COND_CODE_1(CONFIG_UDC_BUF_FORCE_NOCACHE, \
99 : (UDC_HEAP_DEFINE(name, size, __nocache)), \
100 : (UDC_HEAP_DEFINE(name, size, __noinit)))
101 :
102 : extern const struct net_buf_data_cb net_buf_dma_cb;
103 : /** @endcond */
104 :
105 : /**
106 : * @brief Define a new pool for UDC buffers with variable-size payloads
107 : *
108 : * This macro is similar to `NET_BUF_POOL_VAR_DEFINE`, but provides buffers
109 : * with alignment and granularity suitable for use by UDC driver.
110 : *
111 : * @see NET_BUF_POOL_VAR_DEFINE
112 : *
113 : * @param pname Name of the pool variable.
114 : * @param count Number of buffers in the pool.
115 : * @param size Maximum data payload per buffer.
116 : * @param ud_size User data space to reserve per buffer.
117 : * @param fdestroy Optional destroy callback when buffer is freed.
118 : */
119 1 : #define UDC_BUF_POOL_VAR_DEFINE(pname, count, size, ud_size, fdestroy) \
120 : _NET_BUF_ARRAY_DEFINE(pname, count, ud_size); \
121 : UDC_K_HEAP_DEFINE(net_buf_mem_pool_##pname, size); \
122 : static const struct net_buf_data_alloc net_buf_data_alloc_##pname = { \
123 : .cb = &net_buf_dma_cb, \
124 : .alloc_data = &net_buf_mem_pool_##pname, \
125 : .max_alloc_size = 0, \
126 : }; \
127 : static STRUCT_SECTION_ITERABLE(net_buf_pool, pname) = \
128 : NET_BUF_POOL_INITIALIZER(pname, &net_buf_data_alloc_##pname, \
129 : _net_buf_##pname, count, ud_size, \
130 : fdestroy)
131 :
132 : /**
133 : * @brief Define a new pool for UDC buffers based on fixed-size data
134 : *
135 : * This macro is similar to `NET_BUF_POOL_DEFINE`, but provides buffers
136 : * with alignment and granularity suitable for use by UDC driver.
137 : *
138 : * @see NET_BUF_POOL_DEFINE
139 :
140 : * @param pname Name of the pool variable.
141 : * @param count Number of buffers in the pool.
142 : * @param size Maximum data payload per buffer.
143 : * @param ud_size User data space to reserve per buffer.
144 : * @param fdestroy Optional destroy callback when buffer is freed.
145 : */
146 1 : #define UDC_BUF_POOL_DEFINE(pname, count, size, ud_size, fdestroy) \
147 : _NET_BUF_ARRAY_DEFINE(pname, count, ud_size); \
148 : BUILD_ASSERT((UDC_BUF_GRANULARITY) % (UDC_BUF_ALIGN) == 0, \
149 : "Code assumes granurality is multiple of alignment"); \
150 : static uint8_t Z_UDC_BUF_SECTION __aligned(UDC_BUF_ALIGN) \
151 : net_buf_data_##pname[count][ROUND_UP(size, UDC_BUF_GRANULARITY)];\
152 : static const struct net_buf_pool_fixed net_buf_fixed_##pname = { \
153 : .data_pool = (uint8_t *)net_buf_data_##pname, \
154 : }; \
155 : static const struct net_buf_data_alloc net_buf_fixed_alloc_##pname = { \
156 : .cb = &net_buf_fixed_cb, \
157 : .alloc_data = (void *)&net_buf_fixed_##pname, \
158 : .max_alloc_size = ROUND_UP(size, UDC_BUF_GRANULARITY), \
159 : }; \
160 : static STRUCT_SECTION_ITERABLE(net_buf_pool, pname) = \
161 : NET_BUF_POOL_INITIALIZER(pname, &net_buf_fixed_alloc_##pname, \
162 : _net_buf_##pname, count, ud_size, \
163 : fdestroy)
164 :
165 : /**
166 : * @}
167 : */
168 :
169 : #endif /* ZEPHYR_INCLUDE_UDC_BUF_H */
|