Lines Matching +full:dma +full:- +full:enabled

4  * SPDX-License-Identifier: Apache-2.0
17 #include <zephyr/drivers/dma.h>
32 "There is just one DMA controller");
34 #define CHANNEL_COUNT DT_INST_PROP(0, dma_channels) /* number of used/enabled DMA channels */
70 result = -EIO; in dma_si32_isr_handler()
73 __ASSERT(channel_descriptor->CONFIG.TMD == 0, "Result of success: TMD set to zero"); in dma_si32_isr_handler()
74 __ASSERT(channel_descriptor->CONFIG.NCOUNT == 0, in dma_si32_isr_handler()
77 __ASSERT((SI32_DMACTRL_0->CHENSET.U32 & BIT(channel)) == 0, in dma_si32_isr_handler()
101 __ASSERT(SI32_DMACTRL_0 == SI32_DMACTRL_0, "There is only one DMA controller"); in dma_si32_init()
105 /* Route clock to the DMA controller */ in dma_si32_init()
108 /* Configure base address of the DMA channel descriptors */ in dma_si32_init()
111 /* Enable the DMA interface */ in dma_si32_init()
117 /* AN666.pdf: The SCONFIG module contains a bit (FDMAEN) that enables faster DMA transfers in dma_si32_init()
118 * when set to 1. It is recommended that all applications using the DMA set this bit to 1. in dma_si32_init()
141 return -EINVAL; in dma_si32_config()
144 /* Prevent messing up (potentially) ongoing DMA operations and their settings. This behavior in dma_si32_config()
145 * is required by the Zephyr DMA API. in dma_si32_config()
148 LOG_ERR("DMA channel is currently in use"); in dma_si32_config()
149 return -EBUSY; in dma_si32_config()
156 return -EINVAL; in dma_si32_config()
159 if (cfg->complete_callback_en > 1) { in dma_si32_config()
161 return -ENOTSUP; in dma_si32_config()
164 if (cfg->error_callback_dis > 1) { in dma_si32_config()
166 return -ENOTSUP; in dma_si32_config()
169 if (cfg->source_handshake > 1 || cfg->dest_handshake > 1) { in dma_si32_config()
171 return -ENOTSUP; in dma_si32_config()
174 if (cfg->channel_priority > 1) { in dma_si32_config()
176 return -ENOTSUP; in dma_si32_config()
179 if (cfg->source_chaining_en > 1 || cfg->dest_chaining_en > 1) { in dma_si32_config()
181 return -ENOTSUP; in dma_si32_config()
184 if (cfg->linked_channel > 1) { in dma_si32_config()
186 return -ENOTSUP; in dma_si32_config()
189 if (cfg->cyclic > 1) { in dma_si32_config()
191 return -ENOTSUP; in dma_si32_config()
194 if (cfg->source_data_size != 1 && cfg->source_data_size != 2 && in dma_si32_config()
195 cfg->source_data_size != 4) { in dma_si32_config()
196 LOG_ERR("source_data_size must be 1, 2, or 4 (%" PRIu32 ")", cfg->source_data_size); in dma_si32_config()
197 return -ENOTSUP; in dma_si32_config()
200 if (cfg->dest_data_size != 1 && cfg->dest_data_size != 2 && cfg->dest_data_size != 4) { in dma_si32_config()
201 LOG_ERR("dest_data_size must be 1, 2, or 4 (%" PRIu32 ")", cfg->dest_data_size); in dma_si32_config()
202 return -ENOTSUP; in dma_si32_config()
205 __ASSERT(cfg->source_data_size == cfg->dest_data_size, in dma_si32_config()
208 if (cfg->source_burst_length != cfg->dest_burst_length) { in dma_si32_config()
210 return -ENOTSUP; in dma_si32_config()
213 if (POPCOUNT(cfg->source_burst_length) > 1) { in dma_si32_config()
215 return -ENOTSUP; in dma_si32_config()
218 if (cfg->block_count > 1) { in dma_si32_config()
219 LOG_ERR("Scatter-Gather not implemented"); in dma_si32_config()
220 return -ENOTSUP; in dma_si32_config()
225 channel_data->callback = cfg->dma_callback; in dma_si32_config()
226 channel_data->callback_user_data = cfg->user_data; in dma_si32_config()
228 switch (cfg->source_data_size) { in dma_si32_config()
230 channel_descriptor->CONFIG.SRCSIZE = 0b10; in dma_si32_config()
231 channel_descriptor->CONFIG.DSTSIZE = 0b10; in dma_si32_config()
232 channel_descriptor->CONFIG.RPOWER = in dma_si32_config()
233 cfg->source_burst_length ? find_msb_set(cfg->source_burst_length) - 3 : 0; in dma_si32_config()
236 channel_descriptor->CONFIG.SRCSIZE = 0b01; in dma_si32_config()
237 channel_descriptor->CONFIG.DSTSIZE = 0b01; in dma_si32_config()
238 channel_descriptor->CONFIG.RPOWER = in dma_si32_config()
239 cfg->source_burst_length ? find_msb_set(cfg->source_burst_length) - 2 : 0; in dma_si32_config()
242 channel_descriptor->CONFIG.SRCSIZE = 0b00; in dma_si32_config()
243 channel_descriptor->CONFIG.DSTSIZE = 0b00; in dma_si32_config()
244 channel_descriptor->CONFIG.RPOWER = in dma_si32_config()
245 cfg->source_burst_length ? find_msb_set(cfg->source_burst_length) - 1 : 0; in dma_si32_config()
248 LOG_ERR("source_data_size must be 1, 2, or 4 (%" PRIu32 ")", cfg->source_data_size); in dma_si32_config()
249 return -EINVAL; in dma_si32_config()
253 if (!cfg->head_block || cfg->block_count == 0) { in dma_si32_config()
255 return -EINVAL; in dma_si32_config()
258 block = cfg->head_block; in dma_si32_config()
260 if (block->block_size % cfg->source_data_size != 0) { in dma_si32_config()
262 return -EINVAL; in dma_si32_config()
265 if (block->source_address % cfg->source_data_size != 0) { in dma_si32_config()
267 return -EINVAL; in dma_si32_config()
270 if (block->dest_address % cfg->dest_data_size != 0) { in dma_si32_config()
272 return -EINVAL; in dma_si32_config()
275 ncount = block->block_size / cfg->source_data_size - 1; in dma_si32_config()
280 return -EINVAL; in dma_si32_config()
283 channel_descriptor->CONFIG.NCOUNT = ncount; in dma_si32_config()
286 switch (cfg->channel_direction) { in dma_si32_config()
288 /* SiM3U1xx-SiM3C1xx-RM.pdf, 16.6.2. Auto-Request Transfers: This transfer type is in dma_si32_config()
291 channel_data->tmd = SI32_DMADESC_A_CONFIG_TMD_AUTO_REQUEST_VALUE; in dma_si32_config()
292 channel_data->memory_to_memory = 1; in dma_si32_config()
297 /* SiM3U1xx-SiM3C1xx-RM.pdf, 4.3.1. Basic Transfers: This transfer type is in dma_si32_config()
298 * recommended for peripheral-to-memory or memory-to-peripheral transfers. in dma_si32_config()
300 channel_data->tmd = SI32_DMADESC_A_CONFIG_TMD_BASIC_VALUE; in dma_si32_config()
301 channel_data->memory_to_memory = 0; in dma_si32_config()
305 LOG_ERR("Channel direction not implemented: %d", cfg->channel_direction); in dma_si32_config()
306 return -ENOTSUP; in dma_si32_config()
309 switch (block->source_addr_adj) { in dma_si32_config()
311 channel_descriptor->SRCEND.U32 = in dma_si32_config()
312 block->source_address + ncount * cfg->source_data_size; in dma_si32_config()
313 channel_descriptor->CONFIG.SRCAIMD = channel_descriptor->CONFIG.SRCSIZE; in dma_si32_config()
317 return -ENOTSUP; in dma_si32_config()
319 channel_descriptor->SRCEND.U32 = block->source_address; in dma_si32_config()
320 channel_descriptor->CONFIG.SRCAIMD = 0b11; in dma_si32_config()
324 return -EINVAL; in dma_si32_config()
327 switch (block->dest_addr_adj) { in dma_si32_config()
329 channel_descriptor->DSTEND.U32 = block->dest_address + ncount * cfg->dest_data_size; in dma_si32_config()
330 channel_descriptor->CONFIG.DSTAIMD = channel_descriptor->CONFIG.DSTSIZE; in dma_si32_config()
334 return -ENOTSUP; in dma_si32_config()
336 channel_descriptor->DSTEND.U32 = block->dest_address; in dma_si32_config()
337 channel_descriptor->CONFIG.DSTAIMD = 0b11; in dma_si32_config()
341 return -EINVAL; in dma_si32_config()
358 return -EINVAL; in dma_si32_start()
366 __ASSERT(SI32_CLKCTRL_0->AHBCLKG.DMACEN, in dma_si32_start()
367 "AHB clock to the DMA controller must be enabled."); in dma_si32_start()
368 __ASSERT(SI32_DMACTRL_A_is_enabled(SI32_DMACTRL_0), "DMA controller must be enabled."); in dma_si32_start()
369 __ASSERT(SI32_DMACTRL_0->BASEPTR.U32 == (uintptr_t)channel_descriptors, in dma_si32_start()
372 "Primary descriptors must be used for basic and auto-request operations."); in dma_si32_start()
373 __ASSERT(SI32_SCONFIG_0->CONFIG.FDMAEN, "Fast mode is recommened to be enabled."); in dma_si32_start()
374 __ASSERT(SI32_DMACTRL_0->CHSTATUS.U32 & BIT(channel), in dma_si32_start()
377 channel_desc->CONFIG.TMD = channel_data->tmd; in dma_si32_start()
382 /* Enable interrupt for this DMA channels. */ in dma_si32_start()
387 /* memory-to-memory transfers have to be started by this driver. When peripherals are in dma_si32_start()
391 __ASSERT((SI32_DMACTRL_0->CHREQMSET.U32 & BIT(channel)), in dma_si32_start()
395 __ASSERT(!(SI32_DMACTRL_0->CHREQMSET.U32 & BIT(channel)), in dma_si32_start()
396 "Data requests for the channel must be enabled"); in dma_si32_start()
408 return -EINVAL; in dma_si32_stop()
413 channel_descriptors[channel].CONFIG.TMD = 0; /* Stop the DMA channel. */ in dma_si32_stop()
420 static DEVICE_API(dma, dma_si32_driver_api) = {