diff options
Diffstat (limited to 'os')
| -rw-r--r-- | os/hal/platforms/STM32F4xx/stm32_dma.c | 66 | ||||
| -rw-r--r-- | os/hal/platforms/STM32F4xx/stm32_dma.h | 69 | 
2 files changed, 92 insertions, 43 deletions
| diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.c b/os/hal/platforms/STM32F4xx/stm32_dma.c index e35d93543..dd5a92afb 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.c +++ b/os/hal/platforms/STM32F4xx/stm32_dma.c @@ -22,7 +22,7 @@   * @file    STM32F4xx/stm32_dma.c
   * @brief   Enhanced DMA helper driver code.
   *
 - * @addtogroup STM32_DMA
 + * @addtogroup STM32F4xx_DMA
   * @details DMA sharing helper driver. In the STM32 the DMA streams are a
   *          shared resource, this driver allows to allocate and free DMA
   *          streams at runtime in order to allow all the other device
 @@ -76,22 +76,22 @@   *          instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
   */
  const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
 -  {0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0},
 -  {1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6},
 -  {2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16},
 -  {3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22},
 -  {4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0},
 -  {5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6},
 -  {6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16},
 -  {7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22},
 -  {8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0},
 -  {9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6},
 -  {10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16},
 -  {11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22},
 -  {12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0},
 -  {13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6},
 -  {14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16},
 -  {15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22},
 +  {DMA1_Stream0, &DMA1->LIFCR, 0, 0, DMA1_Stream0_IRQn},
 +  {DMA1_Stream1, &DMA1->LIFCR, 6, 1, DMA1_Stream1_IRQn},
 +  {DMA1_Stream2, &DMA1->LIFCR, 16, 2, DMA1_Stream2_IRQn},
 +  {DMA1_Stream3, &DMA1->LIFCR, 22, 3, DMA1_Stream3_IRQn},
 +  {DMA1_Stream4, &DMA1->HIFCR, 0, 4, DMA1_Stream4_IRQn},
 +  {DMA1_Stream5, &DMA1->HIFCR, 6, 5, DMA1_Stream5_IRQn},
 +  {DMA1_Stream6, &DMA1->HIFCR, 16, 6, DMA1_Stream6_IRQn},
 +  {DMA1_Stream7, &DMA1->HIFCR, 22, 7, DMA1_Stream7_IRQn},
 +  {DMA2_Stream0, &DMA2->LIFCR, 0, 8, DMA2_Stream0_IRQn},
 +  {DMA2_Stream1, &DMA2->LIFCR, 6, 9, DMA2_Stream1_IRQn},
 +  {DMA2_Stream2, &DMA2->LIFCR, 16, 10, DMA2_Stream2_IRQn},
 +  {DMA2_Stream3, &DMA2->LIFCR, 22, 11, DMA2_Stream3_IRQn},
 +  {DMA2_Stream4, &DMA2->HIFCR, 0, 12, DMA2_Stream4_IRQn},
 +  {DMA2_Stream5, &DMA2->HIFCR, 6, 13, DMA2_Stream5_IRQn},
 +  {DMA2_Stream6, &DMA2->HIFCR, 16, 14, DMA2_Stream6_IRQn},
 +  {DMA2_Stream7, &DMA2->HIFCR, 22, 15, DMA2_Stream7_IRQn},
  };
  /*===========================================================================*/
 @@ -102,8 +102,8 @@ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {   * @brief   DMA ISR redirector type.
   */
  typedef struct {
 -  stm32_dmaisr_t        dma_func;
 -  void                  *dma_param;
 +  stm32_dmaisr_t        dma_func;       /**< @brief DMA callback function.  */
 +  void                  *dma_param;     /**< @brief DMA callback parameter. */
  } dma_isr_redir_t;
  /**
 @@ -467,7 +467,7 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,    chDbgCheck(dmastp != NULL, "dmaAllocate");
    /* Checks if the stream is already taken.*/
 -  if ((dma_streams_mask & dmastp->mask) != 0)
 +  if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
      return TRUE;
    /* Marks the stream as allocated.*/
 @@ -476,14 +476,10 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,    dma_streams_mask |= (1 << dmastp->selfindex);
    /* Enabling DMA clocks required by the current streams set.*/
 -  if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) {
 -    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
 -    RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN;
 -  }
 -  if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) {
 -    RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
 -    RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN;
 -  }
 +  if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
 +    rccEnableDMA1(FALSE);
 +  if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
 +    rccEnableDMA2(FALSE);
    /* Putting the stream in a safe state.*/
    dmaStreamDisable(dmastp);
 @@ -516,7 +512,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {    chDbgCheck(dmastp != NULL, "dmaRelease");
    /* Check if the streams is not taken.*/
 -  chDbgAssert((dma_streams_mask & dmastp->mask) != 0,
 +  chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
                "dmaRelease(), #1", "not allocated");
    /* Disables the associated IRQ vector.*/
 @@ -526,14 +522,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {    dma_streams_mask &= ~(1 << dmastp->selfindex);
    /* Shutting down clocks that are no more required, if any.*/
 -  if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) {
 -    RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN;
 -    RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN;
 -  }
 -  if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) {
 -    RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN;
 -    RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN;
 -  }
 +  if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
 +    rccDisableDMA1(FALSE);
 +  if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
 +    rccDisableDMA2(FALSE);
  }
  #endif /* STM32_DMA_REQUIRED */
 diff --git a/os/hal/platforms/STM32F4xx/stm32_dma.h b/os/hal/platforms/STM32F4xx/stm32_dma.h index 327b1bc55..9aaadb681 100644 --- a/os/hal/platforms/STM32F4xx/stm32_dma.h +++ b/os/hal/platforms/STM32F4xx/stm32_dma.h @@ -21,8 +21,8 @@  /**
   * @file    STM32F4xx/stm32_dma.h
   * @brief   Enhanced-DMA helper driver header.
 - * @note    This file requires definitions from the ST STM32F2xx header file
 - *          stm32f2xx.h.
 + * @note    This file requires definitions from the ST STM32F4xx header file
 + *          stm32f4xx.h.
   *
   * @addtogroup STM32_DMA
   * @{
 @@ -95,7 +95,7 @@  /** @} */
  /**
 - * @name    CR register constants only found in STM32F2xx
 + * @name    CR register constants only found in STM32F2xx/STM32F4xx
   */
  #define STM32_DMA_CR_DMEIE          DMA_SxCR_DMEIE
  #define STM32_DMA_CR_PFCTRL         DMA_SxCR_PFCTRL
 @@ -155,7 +155,7 @@   * @brief   STM32 DMA stream descriptor structure.
   */
  typedef struct {
 -  DMA_Stream_TypeDef    *stream;       /**< @brief Associated DMA channel. */
 +  DMA_Stream_TypeDef    *stream;        /**< @brief Associated DMA stream.  */
    volatile uint32_t     *ifcr;          /**< @brief Associated IFCR reg.    */
    uint8_t               ishift;         /**< @brief Bits offset in xIFCR
                                               register.                      */
 @@ -179,6 +179,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   Associates a peripheral data register to a DMA stream.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   * @param[in] addr      value to be written in the PAR register
 @@ -192,6 +194,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   Associates a memory destination to a DMA stream.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   * @param[in] addr      value to be written in the M0AR register
 @@ -218,6 +222,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   Sets the number of transfers to be performed.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   * @param[in] size      value to be written in the CNDTR register
 @@ -231,6 +237,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   Returns the number of transfers to be performed.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   * @return              The number of transfers to be performed.
 @@ -242,6 +250,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   Programs the stream mode settings.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   * @param[in] mode      value to be written in the CR register
 @@ -255,6 +265,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   Programs the stream FIFO settings.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   * @param[in] mode      value to be written in the FCR register
 @@ -268,18 +280,22 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   DMA stream enable.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
 - * @param[in] dmachp    pointer to a stm32_dma_stream_t structure
 + * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   *
   * @special
   */
 -#define dmaStreamEnable(dmachp) {                                           \
 +#define dmaStreamEnable(dmastp) {                                           \
    (dmastp)->stream->CR |= STM32_DMA_CR_EN;                                  \
  }
  /**
   * @brief   DMA stream disable.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   *
 @@ -292,6 +308,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);  /**
   * @brief   DMA stream interrupt sources clear.
   * @note    This function can be invoked in both ISR or thread context.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
   *
   * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
   *
 @@ -301,6 +319,45 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);    *(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift;                 \
  }
 +/**
 + * @brief   Starts a memory to memory operation using the specified stream.
 + * @note    The default transfer data mode is "byte to byte" but it can be
 + *          changed by specifying extra options in the @p mode parameter.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
 + *
 + * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
 + * @param[in] mode      value to be written in the CCR register, this value
 + *                      is implicitly ORed with:
 + *                      - @p STM32_DMA_CR_MINC
 + *                      - @p STM32_DMA_CR_PINC
 + *                      - @p STM32_DMA_CR_DIR_M2M
 + *                      - @p STM32_DMA_CR_EN
 + *                      .
 + * @param[in] src       source address
 + * @param[in] dst       destination address
 + * @param[in] n         number of data units to copy
 + */
 +#define dmaStartMemCopy(dmastp, mode, src, dst, n) {                        \
 +  dmaStreamSetPeripheral(dmastp, src);                                      \
 +  dmaStreamSetMemory0(dmastp, dst);                                         \
 +  dmaStreamGetTransactionSize(dmastp, n);                                   \
 +  dmaStreamSetMode(dmastp, (mode) |                                         \
 +                           STM32_DMA_CR_MINC | STM32_DMA_CR_PINC |          \
 +                           STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN);         \
 +}
 +
 +/**
 + * @brief   Polled wait for DMA transfer end.
 + * @pre     The stream must have been allocated using @p dmaStreamAllocate().
 + * @post    After use the stream can be released using @p dmaStreamRelease().
 + *
 + * @param[in] dmastp    pointer to a stm32_dma_stream_t structure
 + */
 +#define dmaWaitCompletion(dmastp)                                           \
 +  while (((dmastp)->stream->CNDTR > 0) &&                                   \
 +         ((dmastp)->stream->CCR & STM32_DMA_CR_EN))
 +
  /*===========================================================================*/
  /* External declarations.                                                    */
  /*===========================================================================*/
 | 
