Paparazzi UAS  v5.15_devel-113-g1b57ff1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
hal_stm32_dma.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Alexandre Bustico, Gautier Hattenberger
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
29 #include "hal_stm32_dma.h"
30 
31 /*
32 TODO :
33 
34 ° split lld and hardware independant code : hal_stm32_dma et hal_lld_stm32_dma
35 
36 ° port to H7,L4+ : bdma, dmav3, mdma+dmamux
37 
38 ° allow fifo burst when STM32_DMA_USE_ASYNC_TIMOUT is true by forcing a flush of the fifo : could be
39  done disabling stream : should flush fifo and trig full code ISR. full code ISR should re-enable stream
40  after a timout.
41 
42 */
43 
44 
51 static void dma_lld_serve_interrupt(DMADriver *dmap, uint32_t flags);
52 
54 {
55  osalDbgCheck(dmap != NULL);
56 
57  dmap->state = DMA_STOP;
58  dmap->config = NULL;
59  dmap->mem0p = NULL;
60 #if STM32_DMA_USE_WAIT == TRUE
61  dmap->thread = NULL;
62 #endif
63 #if STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE
64  osalMutexObjectInit(&dmap->mutex);
65 #endif
66 #if defined( STM32_DMA_DRIVER_EXT_INIT_HOOK)
67  STM32_DMA_DRIVER_EXT_INIT_HOOK(dmap);
68 #endif
69 #if STM32_DMA_USE_ASYNC_TIMOUT
70  chVTObjectInit(&dmap->vt);
71 #endif
72 }
73 
74 
85 bool dmaStart(DMADriver *dmap, const DMAConfig *cfg)
86 {
87  osalDbgCheck((dmap != NULL) && (cfg != NULL));
88 
89  osalSysLock();
90  osalDbgAssert((dmap->state == DMA_STOP) || (dmap->state == DMA_READY),
91  "invalid state");
92  dmap->config = cfg;
93  const bool statusOk = dma_lld_start(dmap);
94  dmap->state = DMA_READY;
95  osalSysUnlock();
96  return statusOk;
97 }
98 
99 
107 void dmaStop(DMADriver *dmap)
108 {
109  osalDbgCheck(dmap != NULL);
110 
111  osalSysLock();
112 
113  osalDbgAssert((dmap->state == DMA_STOP) || (dmap->state == DMA_READY),
114  "invalid state");
115 
116  dma_lld_stop(dmap);
117  dmap->config = NULL;
118  dmap->state = DMA_STOP;
119  dmap->mem0p = NULL;
120 
121  osalSysUnlock();
122 }
123 
124 
142 bool dmaStartTransfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
143 {
144  osalSysLock();
145  const bool statusOk = dmaStartTransfertI(dmap, periphp, mem0p, size);
146  osalSysUnlock();
147  return statusOk;
148 }
149 
167 bool dmaStartTransfertI(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
168 {
169  osalDbgCheckClassI();
170  osalDbgCheck((dmap != NULL) && (mem0p != NULL) && (periphp != NULL) &&
171  (size > 0U) && ((size == 1U) || ((size & 1U) == 0U)));
172 
173 #if (CH_DBG_ENABLE_ASSERTS != FALSE)
174  const DMAConfig *cfg = dmap->config;
175  osalDbgAssert((dmap->state == DMA_READY) ||
176  (dmap->state == DMA_COMPLETE) ||
177  (dmap->state == DMA_ERROR),
178  "not ready");
179 
180  osalDbgAssert((uint32_t) periphp % cfg->psize == 0, "peripheral address not aligned");
181  osalDbgAssert((uint32_t) mem0p % cfg->msize == 0, "memory address not aligned");
182 
183  /*
184  In the circular mode, it is mandatory to respect the following rule in case of a burst mode
185  configured for memory:
186  DMA_SxNDTR = Multiple of ((Mburst beat) × (Msize)/(Psize)), where:
187  – (Mburst beat) = 4, 8 or 16 (depending on the MBURST bits in the DMA_SxCR
188  register)
189  – ((Msize)/(Psize)) = 1, 2, 4, 1/2 or 1/4 (Msize and Psize represent the MSIZE and
190  PSIZE bits in the DMA_SxCR register. They are byte dependent)
191  – DMA_SxNDTR = Number of data items to transfer on the AHB peripheral port
192  */
193 # if STM32_DMA_ADVANCED
194  if (cfg->pburst) {
195  osalDbgAssert((size % (cfg->pburst * cfg->psize)) == 0,
196  "pburst alignment rule not respected");
197  osalDbgAssert((((uint32_t) periphp) % (cfg->pburst * cfg->psize)) == 0,
198  "peripheral address alignment rule not respected");
199  }
200  if (cfg->mburst) {
201  osalDbgAssert((size % (cfg->mburst * cfg->msize)) == 0,
202  "mburst alignment rule not respected");
203  osalDbgAssert((((uint32_t) mem0p) % (cfg->mburst * cfg->msize)) == 0,
204  "memory address alignment rule not respected");
205  }
206 
207 # endif
208 #endif
209 #if STM32_DMA_USE_ASYNC_TIMOUT
210  dmap->currPtr = mem0p;
211  if (dmap->config->timeout != TIME_INFINITE) {
212  chVTSetI(&dmap->vt, dmap->config->timeout,
213  &dma_lld_serve_timeout_interrupt, (void *) dmap);
214  }
215 #endif
216 
217  dmap->state = DMA_ACTIVE;
218  return dma_lld_start_transfert(dmap, periphp, mem0p, size);
219 }
220 
221 
233 {
234 
235  osalDbgCheck(dmap != NULL);
236 
237  osalSysLock();
238  osalDbgAssert((dmap->state == DMA_READY) || (dmap->state == DMA_ACTIVE),
239  "invalid state");
240  if (dmap->state != DMA_READY) {
242  dmap->state = DMA_READY;
243  _dma_reset_s(dmap);
244  }
245  osalSysUnlock();
246 }
247 
248 
249 
261 {
262  osalDbgCheckClassI();
263  osalDbgCheck(dmap != NULL);
264  osalDbgAssert((dmap->state == DMA_READY) ||
265  (dmap->state == DMA_ACTIVE) ||
266  (dmap->state == DMA_COMPLETE),
267  "invalid state");
268 
269 
270  if (dmap->state != DMA_READY) {
272  dmap->state = DMA_READY;
273  _dma_reset_i(dmap);
274  }
275 
276 }
277 
278 #if (STM32_DMA_USE_WAIT == TRUE) || defined(__DOXYGEN__)
279 
303 msg_t dmaTransfertTimeout(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size,
304  sysinterval_t timeout)
305 {
306  msg_t msg;
307 
308  osalSysLock();
309  osalDbgAssert(dmap->thread == NULL, "already waiting");
310  dmaStartTransfertI(dmap, periphp, mem0p, size);
311  msg = osalThreadSuspendTimeoutS(&dmap->thread, timeout);
312  if (msg != MSG_OK) {
313  dmaStopTransfertI(dmap);
314  }
315  osalSysUnlock();
316  return msg;
317 }
318 #endif
319 
320 #if (STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
321 
333 {
334 
335  osalDbgCheck(dmap != NULL);
336 
337  osalMutexLock(&dmap->mutex);
338 }
339 
350 {
351 
352  osalDbgCheck(dmap != NULL);
353 
354  osalMutexUnlock(&dmap->mutex);
355 }
356 #endif /* DMA_USE_MUTUAL_EXCLUSION == TRUE */
357 
358 
359 
360 /*
361 # _ _ _
362 # | | | | | |
363 # | | ___ __ __ | | ___ __ __ ___ | |
364 # | | / _ \ \ \ /\ / / | | / _ \ \ \ / / / _ \ | |
365 # | |____ | (_) | \ V V / | |____ | __/ \ V / | __/ | |
366 # |______| \___/ \_/\_/ |______| \___| \_/ \___| |_|
367 # _____ _
368 # | __ \ (_)
369 # | | | | _ __ _ __ __ ___ _ __
370 # | | | | | '__| | | \ \ / / / _ \ | '__|
371 # | |__| | | | | | \ V / | __/ | |
372 # |_____/ |_| |_| \_/ \___| |_|
373 */
374 
375 
384 {
385  uint32_t psize_msk, msize_msk;
386 
387  const DMAConfig *cfg = dmap->config;
388 
389  switch (cfg->psize) {
390  case 1 : psize_msk = STM32_DMA_CR_PSIZE_BYTE; break;
391  case 2 : psize_msk = STM32_DMA_CR_PSIZE_HWORD; break;
392  case 4 : psize_msk = STM32_DMA_CR_PSIZE_WORD; break;
393  default: osalSysHalt("psize should be 1 or 2 or 4");
394  return false;
395  }
396  switch (cfg->msize) {
397  case 1 : msize_msk = STM32_DMA_CR_MSIZE_BYTE; break;
398  case 2 : msize_msk = STM32_DMA_CR_MSIZE_HWORD; break;
399  case 4 : msize_msk = STM32_DMA_CR_MSIZE_WORD; break;
400  default: osalDbgAssert(false, "msize should be 1 or 2 or 4");
401  return false;
402  }
403 
404  uint32_t dir_msk = 0UL;
405  switch (cfg->direction) {
406  case DMA_DIR_P2M: dir_msk = STM32_DMA_CR_DIR_P2M; break;
407  case DMA_DIR_M2P: dir_msk = STM32_DMA_CR_DIR_M2P; break;
408  case DMA_DIR_M2M: dir_msk = STM32_DMA_CR_DIR_M2M; break;
409  default: osalDbgAssert(false, "direction not set or incorrect");
410  }
411 
412  uint32_t isr_flags = cfg->circular ? 0UL : STM32_DMA_CR_TCIE;
413 
414  if (cfg->direction != DMA_DIR_M2M) {
415  if (cfg->end_cb) {
416  isr_flags |= STM32_DMA_CR_TCIE;
417  if (cfg->circular) {
418  isr_flags |= STM32_DMA_CR_HTIE;
419  }
420  }
421  }
422 
423  if (cfg->error_cb) {
424  isr_flags |= STM32_DMA_CR_DMEIE | STM32_DMA_CR_TCIE;
425  }
426 
427 
428  dmap->dmastream = STM32_DMA_STREAM(cfg->stream);
429 
430  // portable way (V1, V2) to retreive controler number
431 #if STM32_DMA_ADVANCED
432  dmap->controller = 1 + (cfg->stream / STM32_DMA_STREAM_ID(2, 0));
433 #else
434  dmap->controller = 1 + (cfg->stream / STM32_DMA_STREAM_ID(2, 1));
435 #endif
436 
437  dmap->dmamode = STM32_DMA_CR_PL(cfg->dma_priority) |
438  dir_msk | psize_msk | msize_msk | isr_flags |
439  (cfg->circular ? STM32_DMA_CR_CIRC : 0UL) |
440  (cfg->inc_peripheral_addr ? STM32_DMA_CR_PINC : 0UL) |
441  (cfg->inc_memory_addr ? STM32_DMA_CR_MINC : 0UL)
442 
444  | STM32_DMA_CR_CHSEL(cfg->request)
445 #elif STM32_DMA_ADVANCED
446  | STM32_DMA_CR_CHSEL(cfg->channel)
447  | (cfg->periph_inc_size_4 ? STM32_DMA_CR_PINCOS : 0UL) |
448  (cfg->transfert_end_ctrl_by_periph ? STM32_DMA_CR_PFCTRL : 0UL)
449 # endif
450  ;
451 
452 
453 #if STM32_DMA_ADVANCED
454  uint32_t pburst_msk, mburst_msk, fifo_msk; // STM32_DMA_CR_PBURST_INCRx, STM32_DMA_CR_MBURST_INCRx
455  switch (cfg->pburst) {
456  case 0 : pburst_msk = 0UL; break;
457  case 4 : pburst_msk = STM32_DMA_CR_PBURST_INCR4; break;
458  case 8 : pburst_msk = STM32_DMA_CR_PBURST_INCR8; break;
459  case 16 : pburst_msk = STM32_DMA_CR_PBURST_INCR16; break;
460  default: osalDbgAssert(false, "pburst size should be 0 or 4 or 8 or 16");
461  return false;
462  }
463  switch (cfg->mburst) {
464  case 0 : mburst_msk = 0UL; break;
465  case 4 : mburst_msk = STM32_DMA_CR_MBURST_INCR4; break;
466  case 8 : mburst_msk = STM32_DMA_CR_MBURST_INCR8; break;
467  case 16 : mburst_msk = STM32_DMA_CR_MBURST_INCR16; break;
468  default: osalDbgAssert(false, "mburst size should be 0 or 4 or 8 or 16");
469  return false;
470  }
471  switch (cfg->fifo) {
472  case 0 : fifo_msk = 0UL; break;
473  case 1 : fifo_msk = STM32_DMA_FCR_FTH_1Q; break;
474  case 2 : fifo_msk = STM32_DMA_FCR_FTH_HALF; break;
475  case 3 : fifo_msk = STM32_DMA_FCR_FTH_3Q; break;
476  case 4 : fifo_msk = STM32_DMA_FCR_FTH_FULL; ; break;
477  default: osalDbgAssert(false, "fifo threshold should be 1(/4) or 2(/4) or 3(/4) or 4(/4)");
478  return false;
479  }
480 
481 
482 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
483 # if STM32_DMA_USE_ASYNC_TIMOUT
484  osalDbgAssert(dmap->config->timeout != 0,
485  "timeout cannot be 0 if STM32_DMA_USE_ASYNC_TIMOUT is enabled");
486  osalDbgAssert(!((dmap->config->timeout != TIME_INFINITE) && (dmap->config->fifo != 0)),
487  "timeout should be dynamicly disabled (dmap->config->timeout = TIME_INFINITE) "
488  "if STM32_DMA_USE_ASYNC_TIMOUT is enabled and fifo is enabled (fifo != 0)");
489 
490 # endif
491 
492 
493  // lot of combination of parameters are forbiden, and some conditions must be meet
494  if (!cfg->msize != !cfg->psize) {
495  osalDbgAssert(false, "psize and msize should be enabled or disabled together");
496  return false;
497  }
498 
499  if (cfg->fifo) {
500  switch (cfg->msize) {
501  case 1:
502  switch (cfg->mburst) {
503  case 4 :
504  switch (cfg->fifo) {
505  case 1: break;
506  case 2: break;
507  case 3: break;
508  case 4: break;
509  }
510  break;
511  case 8 :
512  switch (cfg->fifo) {
513  case 1: goto forbiddenCombination;
514  case 2: break;
515  case 3: goto forbiddenCombination;
516  case 4: break;
517  }
518  break;
519  case 16 :
520  switch (cfg->fifo) {
521  case 1: goto forbiddenCombination;
522  case 2: goto forbiddenCombination;
523  case 3: goto forbiddenCombination;
524  case 4: break;
525  }
526  break;
527  }
528  break;
529  case 2:
530  switch (cfg->mburst) {
531  case 4 :
532  switch (cfg->fifo) {
533  case 1: goto forbiddenCombination;
534  case 2: break;
535  case 3: goto forbiddenCombination;
536  case 4: break;
537  }
538  break;
539  case 8 :
540  switch (cfg->fifo) {
541  case 1: goto forbiddenCombination;
542  case 2: goto forbiddenCombination;
543  case 3: goto forbiddenCombination;
544  case 4: break;
545  }
546  break;
547  case 16 :
548  switch (cfg->fifo) {
549  case 1: goto forbiddenCombination;
550  case 2: goto forbiddenCombination;
551  case 3: goto forbiddenCombination;
552  case 4: goto forbiddenCombination;
553  }
554  }
555  break;
556  case 4:
557  switch (cfg->mburst) {
558  case 4 :
559  switch (cfg->fifo) {
560  case 1: goto forbiddenCombination;
561  case 2: goto forbiddenCombination;
562  case 3: goto forbiddenCombination;
563  case 4: break;
564  }
565  break;
566  case 8 :
567  switch (cfg->fifo) {
568  case 1: goto forbiddenCombination;
569  case 2: goto forbiddenCombination;
570  case 3: goto forbiddenCombination;
571  case 4: goto forbiddenCombination;
572  }
573  break;
574  case 16 :
575  switch (cfg->fifo) {
576  case 1: goto forbiddenCombination;
577  case 2: goto forbiddenCombination;
578  case 3: goto forbiddenCombination;
579  case 4: goto forbiddenCombination;
580  }
581  }
582  }
583  }
584 # endif
585 
586  dmap->dmamode |= (pburst_msk | mburst_msk);
587 
588 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
589 
590 
591  /*
592  When burst transfers are requested on the peripheral AHB port and the FIFO is used
593  (DMDIS = 1 in the DMA_SxCR register), it is mandatory to respect the following rule to
594  avoid permanent underrun or overrun conditions, depending on the DMA stream direction:
595  If (PBURST × PSIZE) = FIFO_SIZE (4 words), FIFO_Threshold = 3/4 is forbidden
596  */
597 
598  if (((cfg->pburst * cfg->psize) == STM32_DMA_FIFO_SIZE) && (cfg->fifo == 3)) {
599  goto forbiddenCombination;
600  }
601 
602  /*
603  When memory-to-memory mode is used, the Circular and direct modes are not allowed.
604  Only the DMA2 controller is able to perform memory-to-memory transfers.
605  */
606 
607  if (cfg->direction == DMA_DIR_M2M) {
608  osalDbgAssert(dmap->controller == 2, "M2M not available on DMA1");
609  osalDbgAssert(cfg->circular == false, "M2M not available in circular mode");
610  }
611 
612 
613 # endif
614 #endif
615 
616  const bool error = dmaStreamAllocate(dmap->dmastream,
617  cfg->irq_priority,
618  (stm32_dmaisr_t) &dma_lld_serve_interrupt,
619  (void *) dmap);
620  if (error) {
621  osalDbgAssert(false, "stream already allocated");
622  return false;
623  }
624 
625 #if STM32_DMA_ADVANCED
626  if (cfg->fifo) {
627  dmaStreamSetFIFO(dmap->dmastream, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FEIE | fifo_msk);
628  } else {
629  osalDbgAssert(cfg->direction != DMA_DIR_M2M, "fifo mode mandatory for M2M");
630  osalDbgAssert(cfg->psize == cfg->msize, "msize == psize is mandatory when fifo is disabled");
631  }
632 #endif
633 
634 
635 
636  return true;
637 
638 #if (CH_DBG_ENABLE_ASSERTS != FALSE)
639 #if STM32_DMA_ADVANCED
640 forbiddenCombination:
641  chSysHalt("forbidden combination of msize, mburst, fifo, see FIFO threshold "
642  "configuration in reference manuel");
643  return false;
644 # endif
645 #endif
646 }
647 
648 
656 bool dma_lld_start_transfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
657 {
658  dmap->mem0p = mem0p;
659  dmap->size = size;
660  dmaStreamSetPeripheral(dmap->dmastream, periphp);
661  dmaStreamSetMemory0(dmap->dmastream, mem0p);
662  dmaStreamSetTransactionSize(dmap->dmastream, size);
663  dmaStreamSetMode(dmap->dmastream, dmap->dmamode);
664  dmaStreamEnable(dmap->dmastream);
665 
666  return true;
667 }
668 
677 {
678  dmaStreamDisable(dmap->dmastream);
679 }
680 
689 {
690  dmaStreamRelease(dmap->dmastream);
691 }
692 
693 
694 /*===========================================================================*/
695 /* Driver local functions. */
696 /*===========================================================================*/
697 
704 static void dma_lld_serve_interrupt(DMADriver *dmap, uint32_t flags)
705 {
706 
707  /* DMA errors handling.*/
708  if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF | STM32_DMA_ISR_FEIF)) != 0) {
709  /* DMA, this could help only if the DMA tries to access an unmapped
710  address space or violates alignment rules.*/
711  const dmaerrormask_t err =
712  ((flags & STM32_DMA_ISR_TEIF) ? DMA_ERR_TRANSFER_ERROR : 0UL) |
713  ((flags & STM32_DMA_ISR_DMEIF) ? DMA_ERR_DIRECTMODE_ERROR : 0UL) |
714  ((flags & STM32_DMA_ISR_FEIF) ? DMA_ERR_FIFO_ERROR : 0UL);
715 
716  _dma_isr_error_code(dmap, err);
717  } else {
718  /* It is possible that the transaction has already be reset by the
719  DMA error handler, in this case this interrupt is spurious.*/
720  if (dmap->state == DMA_ACTIVE) {
721 
722  if ((flags & STM32_DMA_ISR_TCIF) != 0) {
723  /* Transfer complete processing.*/
724  _dma_isr_full_code(dmap);
725  } else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
726  /* Half transfer processing.*/
727  _dma_isr_half_code(dmap);
728  }
729  }
730  }
731 }
732 
733 #if STM32_DMA_USE_ASYNC_TIMOUT
734 
739 void dma_lld_serve_timeout_interrupt(void *arg)
740 {
741  DMADriver *dmap = (DMADriver *) arg;
742  if (dmap->config->circular) {
743  chSysLockFromISR();
744  chVTSetI(&dmap->vt, dmap->config->timeout,
745  &dma_lld_serve_timeout_interrupt, (void *) dmap);
746  chSysUnlockFromISR();
747  }
748  async_timout_enabled_call_end_cb(dmap, FROM_TIMOUT_CODE);
749 }
750 #endif
Ready.
Definition: hal_stm32_dma.h:62
static float timeout
static void dma_lld_serve_interrupt(DMADriver *dmap, uint32_t flags)
DMA ISR service routine.
msg_t dmaTransfertTimeout(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size, sysinterval_t timeout)
Performs a DMA transaction.
void dmaStop(DMADriver *dmap)
Deactivates the DMA peripheral.
STM32 DMA subsystem driver header.
void dmaStopTransfertI(DMADriver *dmap)
Stops an ongoing transaction.
static void _dma_isr_full_code(DMADriver *dmap)
Common ISR code, full buffer event.
bool inc_peripheral_addr
Enable increment of peripheral address after each transfert.
bool dmaStart(DMADriver *dmap, const DMAConfig *cfg)
Configures and activates the DMA peripheral.
Definition: hal_stm32_dma.c:85
void dmaReleaseBus(DMADriver *dmap)
Releases exclusive access to the DMA peripheral.
dmaerrormask_t
Possible DMA failure causes.
Definition: hal_stm32_dma.h:73
Transfert error.
Definition: hal_stm32_dma.h:65
DMA FIFO overrun or underrun.
Definition: hal_stm32_dma.h:76
uint32_t dmamode
hold DMA CR register for the stream
uint32_t stream
stream associated with transaction
bool inc_memory_addr
Enable increment of memory address after each transfert.
Transfert complete.
Definition: hal_stm32_dma.h:64
dmaerrorcallback_t error_cb
Error callback or NULL.
bool dma_lld_start(DMADriver *dmap)
Configures and activates the DMA peripheral.
dmadirection_t direction
DMA transaction direction.
DMA transfer failure.
Definition: hal_stm32_dma.h:74
dmacallback_t end_cb
Callback function associated to the stream or NULL.
dmastate_t state
Driver state.
void dma_lld_stop(DMADriver *dmap)
Deactivates the DMA peripheral.
MEMORY to MEMORY.
Definition: hal_stm32_dma.h:85
uint8_t psize
DMA peripheral data granurality in bytes (1,2,4)
PERIPHERAL to MEMORY.
Definition: hal_stm32_dma.h:83
bool circular
Enables the circular buffer mode for the stream.
DMA stream configuration structure.
static void _dma_isr_half_code(DMADriver *dmap)
Common ISR code, half buffer event.
uint8_t dma_priority
DMA priority (1 .
unsigned long uint32_t
Definition: types.h:18
DMA Direct Mode failure.
Definition: hal_stm32_dma.h:75
Stopped.
Definition: hal_stm32_dma.h:61
#define STM32_DMA_SUPPORTS_CSELR
Definition: hal_stm32_dma.h:52
void dmaStopTransfert(DMADriver *dmap)
Stops an ongoing transaction.
MEMORY to PERIPHERAL.
Definition: hal_stm32_dma.h:84
size_t size
hold size of current transaction
void dmaAcquireBus(DMADriver *dmap)
Gains exclusive access to the DMA peripheral.
bool dmaStartTransfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
const stm32_dma_stream_t * dmastream
DMA stream associated with peripheral or memory.
void dma_lld_stop_transfert(DMADriver *dmap)
Stops an ongoing transaction.
uint8_t irq_priority
DMA IRQ priority (2 .
void dmaObjectInit(DMADriver *dmap)
Definition: hal_stm32_dma.c:53
#define _dma_reset_i(dmap)
Resumes a thread waiting for a dma transfert completion.
Transfering.
Definition: hal_stm32_dma.h:63
uint8_t msize
DMA memory data granurality in bytes (1,2,4)
uint8_t controller
controller associated with stream
bool dmaStartTransfertI(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
bool dma_lld_start_transfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
static void _dma_isr_error_code(DMADriver *dmap, dmaerrormask_t err)
Common ISR code, error event.
#define _dma_reset_s(dmap)
Resumes a thread waiting for a dma transfert completion.
void * mem0p
memory address
const DMAConfig * config
Current configuration data.
Structure representing a DMA driver.