1 /*
2 * Copyright (c) 2020 - 2024, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRF_VDMA_H__
35 #define NRF_VDMA_H__
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @defgroup nrf_vdma Generic Vector DMA layer.
45 * @{
46 * @ingroup nrf_mvdma
47 * @brief Helper layer that provides the common functionality for Vector DMA (VDMA).
48 */
49
50 /** @brief Maximum size of VDMA buffer. */
51 #define NRF_VDMA_BUFFER_SIZE_MASK VDMADESCRIPTOR_CONFIG_CNT_Msk
52
53 /** @brief Structure describing VDMA job. */
54 typedef struct
55 {
56 uint8_t * p_buffer; ///< Pointer to the VDMA job buffer.
57 struct __PACKED
58 {
59 uint32_t size:24; ///< Size of the job buffer.
60 uint8_t attributes; ///< Attributes of the job.
61 };
62 } nrf_vdma_job_t;
63
64 /** @brief Type describing VDMA job with fixed attributes and length. */
65 typedef uint32_t nrf_vdma_job_reduced_t;
66
67 /**
68 * @brief VDMA attributes.
69 *
70 * @note Only one attribute can be set for the job.
71 */
72 typedef enum
73 {
74 NRF_VDMA_ATTRIBUTE_PLAIN_DATA = 0x00, ///< Data is not modified.
75 NRF_VDMA_ATTRIBUTE_BYTE_SWAP = 0x07, ///< Data bytes are swapped.
76 NRF_VDMA_ATTRIBUTE_JOB_LIST = 0x08, ///< Allows chaining of joblists.
77 NRF_VDMA_ATTRIBUTE_BUFFER_FILL = 0x09, ///< Insters zeros into sink data buffers. Sink job attribute only.
78 NRF_VDMA_ATTRIBUTE_FIXED_ATTR = 0x0A, ///< Identical job attributes and sizes for all jobs in the list.
79 NRF_VDMA_ATTRIBUTE_CRC = 0x0B, ///< CRC checksum is calculated on all data in the source list.
80 NRF_VDMA_ATTRIBUTE_STATIC_ADDR = 0x0C, ///< Memory address is fixed for the entirety of the job.
81 NRF_VDMA_ATTRIBUTE_PLAIN_DATA_BUF_WRITE = 0x0D, ///< Used to get better write performance when many short bursts are beiing sent.
82 } nrf_vdma_attributes_t;
83
84 /**
85 * @brief VDMA extended attributes.
86 *
87 * @note This attributes can be combined with each other and with standard attribute
88 */
89 typedef enum
90 {
91 NRF_VDMA_EXT_ATTRIBUTE_PERIPHERAL_MODE = 0x40, //< Job contains a pointer to a peripheral address.
92 NRF_VDMA_EXT_ATTRIBUTE_EVENT_ENABLE = 0x80, //< Enable event on job completion.
93 } nrf_vdma_ext_attribute_t;
94
95 /**
96 * @brief Macro for computing size of the array of reduced job structures.
97 *
98 * @param[in] count Number of jobs to be stored in reduced job list.
99 */
100 #define NRF_VDMA_REDUCED_JOB_SIZE(count) (count + 2)
101
102 /**
103 * @brief Macro for defining an element of a job list.
104 *
105 * @param[in] p_buffer Pointer to the buffer.
106 * @param[in] size Size of the transfer.
107 * @param[in] attribute Attribute mask.
108 *
109 * @return Two words of the job descriptor.
110 */
111 #define NRF_VDMA_JOB_ELEMENT(p_buffer, size, attribute) \
112 (uint32_t)p_buffer, \
113 (uint32_t)(((attribute) << VDMADESCRIPTOR_CONFIG_ATTRIBUTE_Pos) | \
114 ((size) & NRF_VDMA_BUFFER_SIZE_MASK))
115
116 /**
117 * @brief Macro for defining initial element of reduced job list.
118 *
119 * @param[in] p_buffer Job buffer.
120 * @param[in] size Size of the job buffer.
121 * @param[in] attribute Attributes of the job.
122 *
123 * @return Two words of the job descriptor.
124 */
125 #define NRF_VDMA_REDUCED_JOB_INIT_ELEMENT(p_buffer, size, attribute) \
126 NRF_VDMA_JOB_ELEMENT(p_buffer, size, NRF_VDMA_ATTRIBUTE_FIXED_ATTR | (attribute))
127
128 /**
129 * @brief Macro for defining a job for transfer engaging peripheral.
130 *
131 * @param[in] addr Starting address.
132 * @param[in] size Size of a DMA job.
133 *
134 * @return Two words which contains address, size and the descriptor byte.
135 */
136 #define NRFX_VDMA_PERIPH_JOB(addr, size) \
137 NRF_VDMA_JOB_ELEMENT(addr, size, NRF_VDMA_EXT_ATTRIBUTE_PERIPHERAL_MODE)
138
139 /**
140 * @brief Function for filling the specified structure of the job with given job parameters.
141 *
142 * @param[out] p_job Pointer to the structure of the job to be filled.
143 * @param[in] p_buffer Job buffer.
144 * @param[in] size Size of the job buffer.
145 * @param[in] attributes Attributes of the job.
146 */
nrf_vdma_job_fill(nrf_vdma_job_t * p_job,void * p_buffer,size_t size,uint8_t attributes)147 __STATIC_INLINE void nrf_vdma_job_fill(nrf_vdma_job_t * p_job,
148 void * p_buffer,
149 size_t size,
150 uint8_t attributes)
151 {
152 p_job->p_buffer = (uint8_t *)p_buffer;
153 p_job->size = (uint32_t)size & NRF_VDMA_BUFFER_SIZE_MASK;
154 p_job->attributes = attributes;
155 }
156
157 /**
158 * @brief Function for initializing the specified structure of the job with fixed attributes.
159 *
160 * First element of reduced job list occupies space for two elements.
161 *
162 * @note Use @ref nrf_vdma_job_terminate() to terminate reduced job list.
163 *
164 * @param[out] p_job Pointer to the reduced structure of the job to be filled.
165 * @param[in] p_buffer Job buffer.
166 * @param[in] size Size of the job buffer.
167 * @param[in] attributes Additional attribute of the job.
168 */
nrf_vdma_job_reduced_init(nrf_vdma_job_reduced_t * p_job,void * p_buffer,size_t size,uint8_t attributes)169 __STATIC_INLINE void nrf_vdma_job_reduced_init(nrf_vdma_job_reduced_t * p_job,
170 void * p_buffer,
171 size_t size,
172 uint8_t attributes)
173 {
174 *p_job = (uint32_t)p_buffer;
175 *(p_job + 1) = (uint32_t)(((NRF_VDMA_ATTRIBUTE_FIXED_ATTR | attributes) <<
176 VDMADESCRIPTOR_CONFIG_ATTRIBUTE_Pos) |
177 (size & NRF_VDMA_BUFFER_SIZE_MASK));
178 }
179
180 /**
181 * @brief Function for filling the specified reduced structure of the job with given buffer pointer.
182 *
183 * @param[out] p_job Pointer to the reduced structure of the job to be filled.
184 * @param[in] p_buffer Job buffer.
185 */
nrf_vdma_job_reduced_fill(nrf_vdma_job_reduced_t * p_job,void * p_buffer)186 __STATIC_INLINE void nrf_vdma_job_reduced_fill(nrf_vdma_job_reduced_t * p_job,
187 void * p_buffer)
188 {
189 *p_job = (uint32_t)p_buffer;
190 }
191
192 /**
193 * @brief Function for getting the pointer to the buffer associated with specified job.
194 *
195 * @param[in] p_job Pointer to the structure of the specified job.
196 *
197 * @return Pointer to the job buffer.
198 */
nrf_vdma_job_buffer_get(nrf_vdma_job_t const * p_job)199 __STATIC_INLINE void * nrf_vdma_job_buffer_get(nrf_vdma_job_t const * p_job)
200 {
201 return (void *)p_job->p_buffer;
202 }
203
204 /**
205 * @brief Function for getting the size of the buffer associated with specified job.
206 *
207 * @param[in] p_job Pointer to the structure of the specified job.
208 *
209 * @return Size of the job buffer.
210 */
nrf_vdma_job_size_get(nrf_vdma_job_t const * p_job)211 __STATIC_INLINE size_t nrf_vdma_job_size_get(nrf_vdma_job_t const * p_job)
212 {
213 return (size_t)p_job->size;
214 }
215
216 /**
217 * @brief Function for terminating the specified job.
218 *
219 * When VectorDMA encounters job that is terminated, processing of the job list stops.
220 *
221 * @param[out] p_job Pointer to the structure of the job to be terminated.
222 */
nrf_vdma_job_terminate(nrf_vdma_job_t * p_job)223 __STATIC_INLINE void nrf_vdma_job_terminate(nrf_vdma_job_t * p_job)
224 {
225 p_job->p_buffer = NULL;
226 }
227
228 /**
229 * @brief Function for linking the job with another job.
230 *
231 * When VectorDMA encounters job that is linked to another job,
232 * execution of the linked job starts.
233 *
234 * @param[out] p_job Pointer to the structure of the job to become link.
235 * @param[in] p_job_linked Pointer to the structure of the job to be linked.
236 */
nrf_vdma_job_link(nrf_vdma_job_t * p_job,nrf_vdma_job_t * p_job_linked)237 __STATIC_INLINE void nrf_vdma_job_link(nrf_vdma_job_t * p_job,
238 nrf_vdma_job_t * p_job_linked)
239 {
240 p_job->p_buffer = (uint8_t *)p_job_linked;
241 p_job->attributes = NRF_VDMA_ATTRIBUTE_JOB_LIST;
242 }
243
244 /** @} */
245
246 #ifdef __cplusplus
247 }
248 #endif
249
250 #endif // NRF_VDMA_H__
251