4
0
mirror of https://github.com/RT-Thread/rt-thread.git synced 2025-01-15 06:59:22 +08:00
onelife.real ea6d73f140 *** EFM32 branch ***
1. Upgrade Cortex driver library (CMSIS -> CMSIS & Device): version 2.3.2 -> 3.0.1 & 3.0.0
 - Remove "bsp/efm32/Libraries/CMSIS/Lib/ARM", "bsp/efm32/Libraries/CMSIS/Lib/G++" and "bsp/efm32/Libraries/CMSIS/SVD" to save space
2. Upgrade EFM32 driver libraries (efm32lib -> emlib): version 2.3.2 -> 3.0.0
 - Remove "bsp/efm32/Libraries/Device/EnergyMicro/EFM32LG" and "bsp/efm32/Libraries/Device/EnergyMicro/EFM32TG" to save space
3. Upgrade EFM32GG_DK3750 development kit driver library: version 1.2.2 -> 2.0.1
4. Upgrade EFM32_Gxxx_DK development kit driver library: version 1.7.3 -> 2.0.1
5. Add energy management unit driver and test code
6. Modify linker script and related code to compatible with new version of libraries
7. Change EFM32 branch version number to 1.0
8. Add photo frame demo application

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2122 bbd45198-f89e-11dd-88c7-29a3b14d5316
2012-05-18 04:40:40 +00:00

463 lines
17 KiB
C

/***************************************************************************//**
* @file
* @brief Direct memory access (DMA) API
* @author Energy Micro AS
* @version 3.0.0
*******************************************************************************
* @section License
* <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.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: Energy Micro AS has no
* obligation to support this Software. Energy Micro AS 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.
*
* Energy Micro AS 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 __EM_DMA_H
#define __EM_DMA_H
#include <stdio.h>
#include <stdbool.h>
#include "em_part.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(_EFM32_GIANT_FAMILY)
/**
* 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;
/**
* 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
* according to requirements.
*
* Alignment requirements are
* a) 5 bits base requirement, bits [4:0]
* b) Add the number of bits needed to represent the wanted number
* of channels
* c) Align structure with this number of bits set to zero
*
* Examples: 4 channels, 5 + 2 (channels 0 to 3) = 7 bits
* 7 bit alignment, 64 byte address alignment
* 8 channels, 5 + 3 (channels 0 to 7) = 8 bits
* 8 bit alignment, 256 byte address alignment
* 12 channels, 5 + 4 (channels 0 to 11) = 9 bits
* 9 bit alignment, 512 byte address alignment
*
* 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(_EFM32_GIANT_FAMILY)
void DMA_CfgLoop(unsigned int channel, DMA_CfgLoop_TypeDef *cfg);
void DMA_CfgRect(unsigned int channel, DMA_CfgRect_TypeDef *cfg);
/***************************************************************************//**
* @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;
}
}
/***************************************************************************//**
* @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);
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 /* __EM_DMA_H */