Paparazzi UAS  v5.17_devel-24-g2ae834f
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  NDTR must also be a multiple of the Peripheral size multiplied by the peripheral data
194  size, otherwise this could result in a bad DMA behavior.
195 
196  */
197 # if STM32_DMA_ADVANCED
198  if (cfg->mburst) {
199  osalDbgAssert((size % (cfg->mburst * cfg->msize / cfg->psize)) == 0,
200  "mburst alignment rule not respected");
201  osalDbgAssert((((uint32_t) mem0p) % (cfg->mburst * cfg->msize / cfg->psize)) == 0,
202  "memory address alignment rule not respected");
203  }
204  if (cfg->pburst) {
205  osalDbgAssert((size % (cfg->pburst * cfg->psize)) == 0,
206  "pburst alignment rule not respected");
207  }
208  if (cfg->mburst) {
209  osalDbgAssert((size % (cfg->mburst * cfg->msize)) == 0,
210  "mburst alignment rule not respected");
211  }
212 
213 # endif
214 #endif
215 #if STM32_DMA_USE_ASYNC_TIMOUT
216  dmap->currPtr = mem0p;
217  if (dmap->config->timeout != TIME_INFINITE) {
218  chVTSetI(&dmap->vt, dmap->config->timeout,
219  &dma_lld_serve_timeout_interrupt, (void *) dmap);
220  }
221 #endif
222 
223  dmap->state = DMA_ACTIVE;
224  return dma_lld_start_transfert(dmap, periphp, mem0p, size);
225 }
226 
227 
239 {
240 
241  osalDbgCheck(dmap != NULL);
242 
243  osalSysLock();
244  osalDbgAssert((dmap->state == DMA_READY) || (dmap->state == DMA_ACTIVE),
245  "invalid state");
246  if (dmap->state != DMA_READY) {
248  dmap->state = DMA_READY;
249  _dma_reset_s(dmap);
250  }
251  osalSysUnlock();
252 }
253 
254 
255 
267 {
268  osalDbgCheckClassI();
269  osalDbgCheck(dmap != NULL);
270  osalDbgAssert((dmap->state == DMA_READY) ||
271  (dmap->state == DMA_ACTIVE) ||
272  (dmap->state == DMA_COMPLETE),
273  "invalid state");
274 
275 
276  if (dmap->state != DMA_READY) {
278  dmap->state = DMA_READY;
279  _dma_reset_i(dmap);
280  }
281 
282 }
283 
284 #if (STM32_DMA_USE_WAIT == TRUE) || defined(__DOXYGEN__)
285 
309 msg_t dmaTransfertTimeout(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size,
310  sysinterval_t timeout)
311 {
312  msg_t msg;
313 
314  osalSysLock();
315  osalDbgAssert(dmap->thread == NULL, "already waiting");
316  dmaStartTransfertI(dmap, periphp, mem0p, size);
317  msg = osalThreadSuspendTimeoutS(&dmap->thread, timeout);
318  if (msg != MSG_OK) {
319  dmaStopTransfertI(dmap);
320  }
321  osalSysUnlock();
322  return msg;
323 }
324 #endif
325 
326 #if (STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
327 
339 {
340 
341  osalDbgCheck(dmap != NULL);
342 
343  osalMutexLock(&dmap->mutex);
344 }
345 
356 {
357 
358  osalDbgCheck(dmap != NULL);
359 
360  osalMutexUnlock(&dmap->mutex);
361 }
362 #endif /* DMA_USE_MUTUAL_EXCLUSION == TRUE */
363 
364 
365 
366 /*
367 # _ _ _
368 # | | | | | |
369 # | | ___ __ __ | | ___ __ __ ___ | |
370 # | | / _ \ \ \ /\ / / | | / _ \ \ \ / / / _ \ | |
371 # | |____ | (_) | \ V V / | |____ | __/ \ V / | __/ | |
372 # |______| \___/ \_/\_/ |______| \___| \_/ \___| |_|
373 # _____ _
374 # | __ \ (_)
375 # | | | | _ __ _ __ __ ___ _ __
376 # | | | | | '__| | | \ \ / / / _ \ | '__|
377 # | |__| | | | | | \ V / | __/ | |
378 # |_____/ |_| |_| \_/ \___| |_|
379 */
380 
381 
390 {
391  uint32_t psize_msk, msize_msk;
392 
393  const DMAConfig *cfg = dmap->config;
394 
395  switch (cfg->psize) {
396  case 1 : psize_msk = STM32_DMA_CR_PSIZE_BYTE; break;
397  case 2 : psize_msk = STM32_DMA_CR_PSIZE_HWORD; break;
398  case 4 : psize_msk = STM32_DMA_CR_PSIZE_WORD; break;
399  default: osalSysHalt("psize should be 1 or 2 or 4");
400  return false;
401  }
402  switch (cfg->msize) {
403  case 1 : msize_msk = STM32_DMA_CR_MSIZE_BYTE; break;
404  case 2 : msize_msk = STM32_DMA_CR_MSIZE_HWORD; break;
405  case 4 : msize_msk = STM32_DMA_CR_MSIZE_WORD; break;
406  default: osalDbgAssert(false, "msize should be 1 or 2 or 4");
407  return false;
408  }
409 
410  uint32_t dir_msk = 0UL;
411  switch (cfg->direction) {
412  case DMA_DIR_P2M: dir_msk = STM32_DMA_CR_DIR_P2M; break;
413  case DMA_DIR_M2P: dir_msk = STM32_DMA_CR_DIR_M2P; break;
414  case DMA_DIR_M2M: dir_msk = STM32_DMA_CR_DIR_M2M; break;
415  default: osalDbgAssert(false, "direction not set or incorrect");
416  }
417 
418  uint32_t isr_flags = cfg->circular ? 0UL : STM32_DMA_CR_TCIE;
419 
420  if (cfg->direction != DMA_DIR_M2M) {
421  if (cfg->end_cb) {
422  isr_flags |= STM32_DMA_CR_TCIE;
423  if (cfg->circular) {
424  isr_flags |= STM32_DMA_CR_HTIE;
425  }
426  }
427  }
428 
429  if (cfg->error_cb) {
430  isr_flags |= STM32_DMA_CR_DMEIE | STM32_DMA_CR_TCIE;
431  }
432 
433 
434  dmap->dmastream = STM32_DMA_STREAM(cfg->stream);
435 
436  // portable way (V1, V2) to retreive controler number
437 #if STM32_DMA_ADVANCED
438  dmap->controller = 1 + (cfg->stream / STM32_DMA_STREAM_ID(2, 0));
439 #else
440  dmap->controller = 1 + (cfg->stream / STM32_DMA_STREAM_ID(2, 1));
441 #endif
442 
443  dmap->dmamode = STM32_DMA_CR_PL(cfg->dma_priority) |
444  dir_msk | psize_msk | msize_msk | isr_flags |
445  (cfg->circular ? STM32_DMA_CR_CIRC : 0UL) |
446  (cfg->inc_peripheral_addr ? STM32_DMA_CR_PINC : 0UL) |
447  (cfg->inc_memory_addr ? STM32_DMA_CR_MINC : 0UL)
448 
450  | STM32_DMA_CR_CHSEL(cfg->request)
451 #elif STM32_DMA_ADVANCED
452  | STM32_DMA_CR_CHSEL(cfg->channel)
453  | (cfg->periph_inc_size_4 ? STM32_DMA_CR_PINCOS : 0UL) |
454  (cfg->transfert_end_ctrl_by_periph ? STM32_DMA_CR_PFCTRL : 0UL)
455 # endif
456  ;
457 
458 
459 #if STM32_DMA_ADVANCED
460  uint32_t pburst_msk, mburst_msk, fifo_msk; // STM32_DMA_CR_PBURST_INCRx, STM32_DMA_CR_MBURST_INCRx
461  switch (cfg->pburst) {
462  case 0 : pburst_msk = 0UL; break;
463  case 4 : pburst_msk = STM32_DMA_CR_PBURST_INCR4; break;
464  case 8 : pburst_msk = STM32_DMA_CR_PBURST_INCR8; break;
465  case 16 : pburst_msk = STM32_DMA_CR_PBURST_INCR16; break;
466  default: osalDbgAssert(false, "pburst size should be 0 or 4 or 8 or 16");
467  return false;
468  }
469  switch (cfg->mburst) {
470  case 0 : mburst_msk = 0UL; break;
471  case 4 : mburst_msk = STM32_DMA_CR_MBURST_INCR4; break;
472  case 8 : mburst_msk = STM32_DMA_CR_MBURST_INCR8; break;
473  case 16 : mburst_msk = STM32_DMA_CR_MBURST_INCR16; break;
474  default: osalDbgAssert(false, "mburst size should be 0 or 4 or 8 or 16");
475  return false;
476  }
477  switch (cfg->fifo) {
478  case 0 : fifo_msk = 0UL; break;
479  case 1 : fifo_msk = STM32_DMA_FCR_FTH_1Q; break;
480  case 2 : fifo_msk = STM32_DMA_FCR_FTH_HALF; break;
481  case 3 : fifo_msk = STM32_DMA_FCR_FTH_3Q; break;
482  case 4 : fifo_msk = STM32_DMA_FCR_FTH_FULL; ; break;
483  default: osalDbgAssert(false, "fifo threshold should be 1(/4) or 2(/4) or 3(/4) or 4(/4)");
484  return false;
485  }
486 
487 
488 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
489 # if STM32_DMA_USE_ASYNC_TIMOUT
490  osalDbgAssert(dmap->config->timeout != 0,
491  "timeout cannot be 0 if STM32_DMA_USE_ASYNC_TIMOUT is enabled");
492  osalDbgAssert(!((dmap->config->timeout != TIME_INFINITE) && (dmap->config->fifo != 0)),
493  "timeout should be dynamicly disabled (dmap->config->timeout = TIME_INFINITE) "
494  "if STM32_DMA_USE_ASYNC_TIMOUT is enabled and fifo is enabled (fifo != 0)");
495 
496 # endif
497 
498 
499  // lot of combination of parameters are forbiden, and some conditions must be meet
500  if (!cfg->msize != !cfg->psize) {
501  osalDbgAssert(false, "psize and msize should be enabled or disabled together");
502  return false;
503  }
504 
505  if (cfg->fifo) {
506  switch (cfg->msize) {
507  case 1:
508  switch (cfg->mburst) {
509  case 4 :
510  switch (cfg->fifo) {
511  case 1: break;
512  case 2: break;
513  case 3: break;
514  case 4: break;
515  }
516  break;
517  case 8 :
518  switch (cfg->fifo) {
519  case 1: goto forbiddenCombination;
520  case 2: break;
521  case 3: goto forbiddenCombination;
522  case 4: break;
523  }
524  break;
525  case 16 :
526  switch (cfg->fifo) {
527  case 1: goto forbiddenCombination;
528  case 2: goto forbiddenCombination;
529  case 3: goto forbiddenCombination;
530  case 4: break;
531  }
532  break;
533  }
534  break;
535  case 2:
536  switch (cfg->mburst) {
537  case 4 :
538  switch (cfg->fifo) {
539  case 1: goto forbiddenCombination;
540  case 2: break;
541  case 3: goto forbiddenCombination;
542  case 4: break;
543  }
544  break;
545  case 8 :
546  switch (cfg->fifo) {
547  case 1: goto forbiddenCombination;
548  case 2: goto forbiddenCombination;
549  case 3: goto forbiddenCombination;
550  case 4: break;
551  }
552  break;
553  case 16 :
554  switch (cfg->fifo) {
555  case 1: goto forbiddenCombination;
556  case 2: goto forbiddenCombination;
557  case 3: goto forbiddenCombination;
558  case 4: goto forbiddenCombination;
559  }
560  }
561  break;
562  case 4:
563  switch (cfg->mburst) {
564  case 4 :
565  switch (cfg->fifo) {
566  case 1: goto forbiddenCombination;
567  case 2: goto forbiddenCombination;
568  case 3: goto forbiddenCombination;
569  case 4: break;
570  }
571  break;
572  case 8 :
573  switch (cfg->fifo) {
574  case 1: goto forbiddenCombination;
575  case 2: goto forbiddenCombination;
576  case 3: goto forbiddenCombination;
577  case 4: goto forbiddenCombination;
578  }
579  break;
580  case 16 :
581  switch (cfg->fifo) {
582  case 1: goto forbiddenCombination;
583  case 2: goto forbiddenCombination;
584  case 3: goto forbiddenCombination;
585  case 4: goto forbiddenCombination;
586  }
587  }
588  }
589  }
590 # endif
591 
592  dmap->dmamode |= (pburst_msk | mburst_msk);
593 
594 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
595 
596 
597  /*
598  When burst transfers are requested on the peripheral AHB port and the FIFO is used
599  (DMDIS = 1 in the DMA_SxCR register), it is mandatory to respect the following rule to
600  avoid permanent underrun or overrun conditions, depending on the DMA stream direction:
601  If (PBURST × PSIZE) = FIFO_SIZE (4 words), FIFO_Threshold = 3/4 is forbidden
602  */
603 
604  if (((cfg->pburst * cfg->psize) == STM32_DMA_FIFO_SIZE) && (cfg->fifo == 3)) {
605  goto forbiddenCombination;
606  }
607 
608  /*
609  When memory-to-memory mode is used, the Circular and direct modes are not allowed.
610  Only the DMA2 controller is able to perform memory-to-memory transfers.
611  */
612 
613  if (cfg->direction == DMA_DIR_M2M) {
614  osalDbgAssert(dmap->controller == 2, "M2M not available on DMA1");
615  osalDbgAssert(cfg->circular == false, "M2M not available in circular mode");
616  }
617 
618 
619 # endif
620 #endif
621 
622  const bool error = dmaStreamAllocate(dmap->dmastream,
623  cfg->irq_priority,
624  (stm32_dmaisr_t) &dma_lld_serve_interrupt,
625  (void *) dmap);
626  if (error) {
627  osalDbgAssert(false, "stream already allocated");
628  return false;
629  }
630 
631 #if STM32_DMA_ADVANCED
632  if (cfg->fifo) {
633  dmaStreamSetFIFO(dmap->dmastream, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FEIE | fifo_msk);
634  } else {
635  osalDbgAssert(cfg->direction != DMA_DIR_M2M, "fifo mode mandatory for M2M");
636  osalDbgAssert(cfg->psize == cfg->msize, "msize == psize is mandatory when fifo is disabled");
637  }
638 #endif
639 
640 
641 
642  return true;
643 
644 #if (CH_DBG_ENABLE_ASSERTS != FALSE)
645 #if STM32_DMA_ADVANCED
646 forbiddenCombination:
647  chSysHalt("forbidden combination of msize, mburst, fifo, see FIFO threshold "
648  "configuration in reference manuel");
649  return false;
650 # endif
651 #endif
652 }
653 
654 
662 bool dma_lld_start_transfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
663 {
664  dmap->mem0p = mem0p;
665  dmap->size = size;
666  dmaStreamSetPeripheral(dmap->dmastream, periphp);
667  dmaStreamSetMemory0(dmap->dmastream, mem0p);
668  dmaStreamSetTransactionSize(dmap->dmastream, size);
669  dmaStreamSetMode(dmap->dmastream, dmap->dmamode);
670  dmaStreamEnable(dmap->dmastream);
671 
672  return true;
673 }
674 
683 {
684  dmaStreamDisable(dmap->dmastream);
685 }
686 
695 {
696  dmaStreamRelease(dmap->dmastream);
697 }
698 
699 
700 /*===========================================================================*/
701 /* Driver local functions. */
702 /*===========================================================================*/
703 
710 static void dma_lld_serve_interrupt(DMADriver *dmap, uint32_t flags)
711 {
712 
713  /* DMA errors handling.*/
714  if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF | STM32_DMA_ISR_FEIF)) != 0) {
715  /* DMA, this could help only if the DMA tries to access an unmapped
716  address space or violates alignment rules.*/
717  const dmaerrormask_t err =
718  ((flags & STM32_DMA_ISR_TEIF) ? DMA_ERR_TRANSFER_ERROR : 0UL) |
719  ((flags & STM32_DMA_ISR_DMEIF) ? DMA_ERR_DIRECTMODE_ERROR : 0UL) |
720  ((flags & STM32_DMA_ISR_FEIF) ? DMA_ERR_FIFO_ERROR : 0UL);
721 
722  _dma_isr_error_code(dmap, err);
723  } else {
724  /* It is possible that the transaction has already be reset by the
725  DMA error handler, in this case this interrupt is spurious.*/
726  if (dmap->state == DMA_ACTIVE) {
727 
728  if ((flags & STM32_DMA_ISR_TCIF) != 0) {
729  /* Transfer complete processing.*/
730  _dma_isr_full_code(dmap);
731  } else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
732  /* Half transfer processing.*/
733  _dma_isr_half_code(dmap);
734  }
735  }
736  }
737 }
738 
739 #if STM32_DMA_USE_ASYNC_TIMOUT
740 
745 void dma_lld_serve_timeout_interrupt(void *arg)
746 {
747  DMADriver *dmap = (DMADriver *) arg;
748  if (dmap->config->circular) {
749  chSysLockFromISR();
750  chVTSetI(&dmap->vt, dmap->config->timeout,
751  &dma_lld_serve_timeout_interrupt, (void *) dmap);
752  chSysUnlockFromISR();
753  }
754  async_timout_enabled_call_end_cb(dmap, FROM_TIMOUT_CODE);
755 }
756 #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.
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
volatile dmastate_t state
Driver state.
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.