mbed official / mbed

Dependents:   hello SerialTestv11 SerialTestv12 Sierpinski ... more

Revision:
98:8ab26030e058
Child:
113:f141b2784e32
diff -r 433970e64889 -r 8ab26030e058 TARGET_EFM32ZG_STK3200/TARGET_Silicon_Labs/TARGET_EFM32/emlib/inc/em_dma.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TARGET_EFM32ZG_STK3200/TARGET_Silicon_Labs/TARGET_EFM32/emlib/inc/em_dma.h	Wed Apr 29 10:16:23 2015 +0100
@@ -0,0 +1,463 @@
+/***************************************************************************//**
+ * @file em_dma.h
+ * @brief Direct memory access (DMA) API
+ * @version 3.20.12
+ *******************************************************************************
+ * @section License
+ * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
+ *******************************************************************************
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
+ * obligation to support this Software. Silicon Labs is providing the
+ * Software "AS IS", with no express or implied warranties of any kind,
+ * including, but not limited to, any implied warranties of merchantability
+ * or fitness for any particular purpose or warranties against infringement
+ * of any proprietary rights of a third party.
+ *
+ * Silicon Labs will not be liable for any consequential, incidental, or
+ * special damages, or any other relief, or for any claim by any third party,
+ * arising from your use of this Software.
+ *
+ ******************************************************************************/
+
+
+
+#ifndef __SILICON_LABS_EM_DMA_H_
+#define __SILICON_LABS_EM_DMA_H_
+
+#include "em_device.h"
+#if defined( DMA_PRESENT )
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************************************************************//**
+ * @addtogroup EM_Library
+ * @{
+ ******************************************************************************/
+
+/***************************************************************************//**
+ * @addtogroup DMA
+ * @{
+ ******************************************************************************/
+
+/*******************************************************************************
+ ********************************   ENUMS   ************************************
+ ******************************************************************************/
+
+/**
+ * Amount source/destination address should be incremented for each data
+ * transfer.
+ */
+typedef enum
+{
+  dmaDataInc1    = _DMA_CTRL_SRC_INC_BYTE,     /**< Increment address 1 byte. */
+  dmaDataInc2    = _DMA_CTRL_SRC_INC_HALFWORD, /**< Increment address 2 bytes. */
+  dmaDataInc4    = _DMA_CTRL_SRC_INC_WORD,     /**< Increment address 4 bytes. */
+  dmaDataIncNone = _DMA_CTRL_SRC_INC_NONE      /**< Do not increment address. */
+} DMA_DataInc_TypeDef;
+
+
+/** Data sizes (in number of bytes) to be read/written by DMA transfer. */
+typedef enum
+{
+  dmaDataSize1 = _DMA_CTRL_SRC_SIZE_BYTE,     /**< 1 byte DMA transfer size. */
+  dmaDataSize2 = _DMA_CTRL_SRC_SIZE_HALFWORD, /**< 2 byte DMA transfer size. */
+  dmaDataSize4 = _DMA_CTRL_SRC_SIZE_WORD      /**< 4 byte DMA transfer size. */
+} DMA_DataSize_TypeDef;
+
+
+/** Type of DMA transfer. */
+typedef enum
+{
+  /** Basic DMA cycle. */
+  dmaCycleCtrlBasic            = _DMA_CTRL_CYCLE_CTRL_BASIC,
+  /** Auto-request DMA cycle. */
+  dmaCycleCtrlAuto             = _DMA_CTRL_CYCLE_CTRL_AUTO,
+  /** Ping-pong DMA cycle. */
+  dmaCycleCtrlPingPong         = _DMA_CTRL_CYCLE_CTRL_PINGPONG,
+  /** Memory scatter-gather DMA cycle. */
+  dmaCycleCtrlMemScatterGather = _DMA_CTRL_CYCLE_CTRL_MEM_SCATTER_GATHER,
+  /** Peripheral scatter-gather DMA cycle. */
+  dmaCycleCtrlPerScatterGather = _DMA_CTRL_CYCLE_CTRL_PER_SCATTER_GATHER
+} DMA_CycleCtrl_TypeDef;
+
+
+/** Number of transfers before controller does new arbitration. */
+typedef enum
+{
+  dmaArbitrate1    = _DMA_CTRL_R_POWER_1,    /**< Arbitrate after 1 DMA transfer. */
+  dmaArbitrate2    = _DMA_CTRL_R_POWER_2,    /**< Arbitrate after 2 DMA transfers. */
+  dmaArbitrate4    = _DMA_CTRL_R_POWER_4,    /**< Arbitrate after 4 DMA transfers. */
+  dmaArbitrate8    = _DMA_CTRL_R_POWER_8,    /**< Arbitrate after 8 DMA transfers. */
+  dmaArbitrate16   = _DMA_CTRL_R_POWER_16,   /**< Arbitrate after 16 DMA transfers. */
+  dmaArbitrate32   = _DMA_CTRL_R_POWER_32,   /**< Arbitrate after 32 DMA transfers. */
+  dmaArbitrate64   = _DMA_CTRL_R_POWER_64,   /**< Arbitrate after 64 DMA transfers. */
+  dmaArbitrate128  = _DMA_CTRL_R_POWER_128,  /**< Arbitrate after 128 DMA transfers. */
+  dmaArbitrate256  = _DMA_CTRL_R_POWER_256,  /**< Arbitrate after 256 DMA transfers. */
+  dmaArbitrate512  = _DMA_CTRL_R_POWER_512,  /**< Arbitrate after 512 DMA transfers. */
+  dmaArbitrate1024 = _DMA_CTRL_R_POWER_1024  /**< Arbitrate after 1024 DMA transfers. */
+} DMA_ArbiterConfig_TypeDef;
+
+
+/*******************************************************************************
+ *******************************   STRUCTS   ***********************************
+ ******************************************************************************/
+
+/**
+ * @brief
+ *   DMA interrupt callback function pointer.
+ * @details
+ *   Parameters:
+ *   @li channel - The DMA channel the callback function is invoked for.
+ *   @li primary - Indicates if callback is invoked for completion of primary
+ *     (true) or alternate (false) descriptor. This is mainly useful for
+ *     ping-pong DMA cycles, in order to know which descriptor to refresh.
+ *   @li user - User definable reference that may be used to pass information
+ *     to be used by the callback handler. If used, the referenced data must be
+ *     valid at the point when the interrupt handler invokes the callback.
+ *     If callback changes  any data in the provided user structure, remember
+ *     that those changes are done in interrupt context, and proper protection
+ *     of data may be required.
+ */
+typedef void (*DMA_FuncPtr_TypeDef)(unsigned int channel, bool primary, void *user);
+
+
+/**
+ * @brief
+ *   Callback structure that can be used to define DMA complete actions.
+ * @details
+ *   A reference to this structure is only stored in the primary descriptor
+ *   for a channel (if callback feature is used). If callback is required
+ *   for both primary and alternate descriptor completion, this must be
+ *   handled by one common callback, using the provided 'primary' parameter
+ *   with the callback function.
+ */
+typedef struct
+{
+  /**
+   * Pointer to callback function to invoke when DMA transfer cycle done.
+   * Notice that this function is invoked in interrupt context, and therefore
+   * should be short and non-blocking.
+   */
+  DMA_FuncPtr_TypeDef cbFunc;
+
+  /** User defined pointer to provide with callback function. */
+  void                *userPtr;
+
+  /**
+   * For internal use only: Indicates if next callback applies to primary
+   * or alternate descriptor completion. Mainly useful for ping-pong DMA
+   * cycles. Set this value to 0 prior to configuring callback handling.
+   */
+  uint8_t             primary;
+} DMA_CB_TypeDef;
+
+
+/** Configuration structure for a channel. */
+typedef struct
+{
+  /**
+   * Select if channel priority is in the high or default priority group
+   * with respect to arbitration. Within a priority group, lower numbered
+   * channels have higher priority than higher numbered channels.
+   */
+  bool     highPri;
+
+  /**
+   * Select if interrupt shall be enabled for channel (triggering interrupt
+   * handler when dma_done signal is asserted). It should normally be
+   * enabled if using the callback feature for a channel, and disabled if
+   * not using the callback feature.
+   */
+  bool     enableInt;
+
+  /**
+   * Channel control specifying the source of DMA signals. If accessing
+   * peripherals, use one of the DMAREQ_nnn defines available for the
+   * peripheral. Set it to 0 for memory-to-memory DMA cycles.
+   */
+  uint32_t select;
+
+  /**
+   * @brief
+   *   User definable callback handling configuration.
+   * @details
+   *   Please refer to structure definition for details. The callback
+   *   is invoked when the specified DMA cycle is complete (when dma_done
+   *   signal asserted). The callback is invoked in interrupt context,
+   *   and should be efficient and non-blocking. Set to NULL to not
+   *   use the callback feature.
+   * @note
+   *   The referenced structure is used by the interrupt handler, and must
+   *   be available until no longer used. Thus, in most cases it should
+   *   not be located on the stack.
+   */
+  DMA_CB_TypeDef *cb;
+} DMA_CfgChannel_TypeDef;
+
+
+/**
+ * Configuration structure for primary or alternate descriptor
+ * (not used for scatter-gather DMA cycles).
+ */
+typedef struct
+{
+  /** Destination increment size for each DMA transfer */
+  DMA_DataInc_TypeDef       dstInc;
+
+  /** Source increment size for each DMA transfer */
+  DMA_DataInc_TypeDef       srcInc;
+
+  /** DMA transfer unit size. */
+  DMA_DataSize_TypeDef      size;
+
+  /**
+   * Arbitration rate, ie number of DMA transfers done before rearbitration
+   * takes place.
+   */
+  DMA_ArbiterConfig_TypeDef arbRate;
+
+  /**
+   * HPROT signal state, please refer to reference manual, DMA chapter for
+   * further details. Normally set to 0 if protection is not an issue.
+   * The following bits are available:
+   * @li bit 0 - HPROT[1] control for source read accesses,
+   *   privileged/non-privileged access
+   * @li bit 3 - HPROT[1] control for destination write accesses,
+   *   privileged/non-privileged access
+   */
+  uint8_t hprot;
+} DMA_CfgDescr_TypeDef;
+
+
+#if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
+/**
+ * Configuration structure for loop mode
+ */
+typedef struct
+{
+  /** Enable repeated loop */
+  bool      enable;
+  /** Width of transfer, reload value for nMinus1 */
+  uint16_t  nMinus1;
+} DMA_CfgLoop_TypeDef;
+#endif
+
+
+#if defined( _DMA_RECT0_MASK )
+/**
+ * Configuration structure for rectangular copy
+ */
+typedef struct
+{
+  /** DMA channel destination stride (width of destination image, distance between lines) */
+  uint16_t dstStride;
+  /** DMA channel source stride (width of source image, distance between lines) */
+  uint16_t srcStride;
+  /** 2D copy height */
+  uint16_t height;
+} DMA_CfgRect_TypeDef;
+#endif
+
+
+/** Configuration structure for alternate scatter-gather descriptor. */
+typedef struct
+{
+  /** Pointer to location to transfer data from. */
+  void                      *src;
+
+  /** Pointer to location to transfer data to. */
+  void                      *dst;
+
+  /** Destination increment size for each DMA transfer */
+  DMA_DataInc_TypeDef       dstInc;
+
+  /** Source increment size for each DMA transfer */
+  DMA_DataInc_TypeDef       srcInc;
+
+  /** DMA transfer unit size. */
+  DMA_DataSize_TypeDef      size;
+
+  /**
+   * Arbitration rate, ie number of DMA transfers done before rearbitration
+   * takes place.
+   */
+  DMA_ArbiterConfig_TypeDef arbRate;
+
+  /** Number of DMA transfers minus 1 to do. Must be <= 1023. */
+  uint16_t                  nMinus1;
+
+  /**
+   * HPROT signal state, please refer to reference manual, DMA chapter for
+   * further details. Normally set to 0 if protection is not an issue.
+   * The following bits are available:
+   * @li bit 0 - HPROT[1] control for source read accesses,
+   *   privileged/non-privileged access
+   * @li bit 3 - HPROT[1] control for destination write accesses,
+   *   privileged/non-privileged access
+   */
+  uint8_t hprot;
+
+  /** Specify if a memory or peripheral scatter-gather DMA cycle. Notice
+   *  that this parameter should be the same for all alternate
+   *  descriptors.
+   *  @li true - this is a peripheral scatter-gather cycle
+   *  @li false - this is a memory scatter-gather cycle
+   */
+  bool    peripheral;
+} DMA_CfgDescrSGAlt_TypeDef;
+
+
+/** DMA init structure */
+typedef struct
+{
+  /**
+   * HPROT signal state when accessing the primary/alternate
+   * descriptors. Normally set to 0 if protection is not an issue.
+   * The following bits are available:
+   * @li bit 0 - HPROT[1] control for descriptor accesses (ie when
+   *   the DMA controller accesses the channel control block itself),
+   *   privileged/non-privileged access
+   */
+  uint8_t hprot;
+
+  /**
+   * Pointer to the controlblock in memory holding descriptors (channel
+   * control data structures). This memory must be properly aligned
+   * at a 256 bytes. I.e. the 8 least significant bits must be zero.
+   *
+   * Please refer to the reference manual, DMA chapter for more details.
+   *
+   * It is possible to provide a smaller memory block, only covering
+   * those channels actually used, if not all available channels are used.
+   * Ie, if only using 4 channels (0-3), both primary and alternate
+   * structures, then only 16*2*4 = 128 bytes must be provided. This
+   * implementation has however no check if later exceeding such a limit
+   * by configuring for instance channel 4, in which case memory overwrite
+   * of some other data will occur.
+   */
+  DMA_DESCRIPTOR_TypeDef *controlBlock;
+} DMA_Init_TypeDef;
+
+
+/*******************************************************************************
+ *****************************   PROTOTYPES   **********************************
+ ******************************************************************************/
+
+void DMA_ActivateAuto(unsigned int channel,
+                      bool primary,
+                      void *dst,
+                      void *src,
+                      unsigned int nMinus1);
+void DMA_ActivateBasic(unsigned int channel,
+                       bool primary,
+                       bool useBurst,
+                       void *dst,
+                       void *src,
+                       unsigned int nMinus1);
+void DMA_ActivatePingPong(unsigned int channel,
+                          bool useBurst,
+                          void *primDst,
+                          void *primSrc,
+                          unsigned int primNMinus1,
+                          void *altDst,
+                          void *altSrc,
+                          unsigned int altNMinus1);
+void DMA_ActivateScatterGather(unsigned int channel,
+                               bool useBurst,
+                               DMA_DESCRIPTOR_TypeDef *altDescr,
+                               unsigned int count);
+void DMA_CfgChannel(unsigned int channel, DMA_CfgChannel_TypeDef *cfg);
+void DMA_CfgDescr(unsigned int channel,
+                  bool primary,
+                  DMA_CfgDescr_TypeDef *cfg);
+#if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
+void DMA_CfgLoop(unsigned int channel, DMA_CfgLoop_TypeDef *cfg);
+#endif
+
+#if defined( _DMA_RECT0_MASK )
+void DMA_CfgRect(unsigned int channel, DMA_CfgRect_TypeDef *cfg);
+#endif
+
+#if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
+/***************************************************************************//**
+ * @brief
+ *   Clear Loop configuration for channel
+ *
+ * @param[in] channel
+ *   Channel to reset loop configuration for
+ ******************************************************************************/
+__STATIC_INLINE void DMA_ResetLoop(unsigned int channel)
+{
+  /* Clean loop copy operation */
+  switch(channel)
+  {
+  case 0:
+    DMA->LOOP0 = _DMA_LOOP0_RESETVALUE;
+    break;
+  case 1:
+    DMA->LOOP1 = _DMA_LOOP1_RESETVALUE;
+    break;
+  default:
+    break;
+  }
+}
+#endif
+
+
+#if defined( _DMA_RECT0_MASK )
+/***************************************************************************//**
+ * @brief
+ *   Clear Rect/2D DMA configuration for channel
+ *
+ * @param[in] channel
+ *   Channel to reset loop configuration for
+ ******************************************************************************/
+__STATIC_INLINE void DMA_ResetRect(unsigned int channel)
+{
+  (void) channel;
+
+  /* Clear rect copy operation */
+  DMA->RECT0 = _DMA_RECT0_RESETVALUE;
+}
+#endif
+void DMA_CfgDescrScatterGather(DMA_DESCRIPTOR_TypeDef *descr,
+                               unsigned int indx,
+                               DMA_CfgDescrSGAlt_TypeDef *cfg);
+void DMA_ChannelEnable(unsigned int channel, bool enable);
+bool DMA_ChannelEnabled(unsigned int channel);
+void DMA_Init(DMA_Init_TypeDef *init);
+void DMA_IRQHandler(void);
+void DMA_RefreshPingPong(unsigned int channel,
+                         bool primary,
+                         bool useBurst,
+                         void *dst,
+                         void *src,
+                         unsigned int nMinus1,
+                         bool last);
+void DMA_Reset(void);
+
+/** @} (end addtogroup DMA) */
+/** @} (end addtogroup EM_Library) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* defined( DMA_PRESENT ) */
+#endif /* __SILICON_LABS_EM_DMA_H_ */