Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
Diff: targets/TARGET_Silicon_Labs/TARGET_EFM32/emlib/inc/em_ldma.h
- Revision:
- 149:156823d33999
- Parent:
- 50:a417edff4437
- Child:
- 150:02e0a0aed4ec
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/emlib/inc/em_ldma.h Fri Oct 28 11:17:30 2016 +0100 @@ -0,0 +1,1330 @@ +/***************************************************************************//** + * @file em_ldma.h + * @brief Direct memory access (LDMA) API + * @version 4.2.1 + ******************************************************************************* + * @section License + * <b>(C) Copyright 2015 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.@n + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software.@n + * 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_LDMA_H__ +#define __SILICON_LABS_EM_LDMA_H__ + +#include "em_device.h" + +#if defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 ) + +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/***************************************************************************//** + * @addtogroup EM_Library + * @{ + ******************************************************************************/ + +/***************************************************************************//** + * @addtogroup LDMA + * @{ + ******************************************************************************/ + +/******************************************************************************* + ******************************** ENUMS ************************************ + ******************************************************************************/ + +/** + * This value controls the number of unit data transfers per arbitration + * cycle, providing a means to balance DMA channels' load on the controller. + */ +typedef enum +{ + ldmaCtrlBlockSizeUnit1 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT1, /**< One transfer per arbitration. */ + ldmaCtrlBlockSizeUnit2 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT2, /**< Two transfers per arbitration. */ + ldmaCtrlBlockSizeUnit3 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT3, /**< Three transfers per arbitration. */ + ldmaCtrlBlockSizeUnit4 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT4, /**< Four transfers per arbitration. */ + ldmaCtrlBlockSizeUnit6 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT6, /**< Six transfers per arbitration. */ + ldmaCtrlBlockSizeUnit8 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT8, /**< Eight transfers per arbitration. */ + ldmaCtrlBlockSizeUnit16 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT16, /**< 16 transfers per arbitration. */ + ldmaCtrlBlockSizeUnit32 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT32, /**< 32 transfers per arbitration. */ + ldmaCtrlBlockSizeUnit64 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT64, /**< 64 transfers per arbitration. */ + ldmaCtrlBlockSizeUnit128 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT128, /**< 128 transfers per arbitration. */ + ldmaCtrlBlockSizeUnit256 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT256, /**< 256 transfers per arbitration. */ + ldmaCtrlBlockSizeUnit512 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT512, /**< 512 transfers per arbitration. */ + ldmaCtrlBlockSizeUnit1024 = _LDMA_CH_CTRL_BLOCKSIZE_UNIT1024, /**< 1024 transfers per arbitration. */ + ldmaCtrlBlockSizeAll = _LDMA_CH_CTRL_BLOCKSIZE_ALL /**< Lock arbitration during transfer. */ +} LDMA_CtrlBlockSize_t; + +/** DMA structure type. */ +typedef enum +{ + ldmaCtrlStructTypeXfer = _LDMA_CH_CTRL_STRUCTTYPE_TRANSFER, /**< TRANSFER transfer type. */ + ldmaCtrlStructTypeSync = _LDMA_CH_CTRL_STRUCTTYPE_SYNCHRONIZE, /**< SYNCHRONIZE transfer type. */ + ldmaCtrlStructTypeWrite = _LDMA_CH_CTRL_STRUCTTYPE_WRITE /**< WRITE transfer type. */ +} LDMA_CtrlStructType_t; + +/** DMA transfer block or cycle selector. */ +typedef enum +{ + ldmaCtrlReqModeBlock = _LDMA_CH_CTRL_REQMODE_BLOCK, /**< Each DMA request trigger transfer of one block. */ + ldmaCtrlReqModeAll = _LDMA_CH_CTRL_REQMODE_ALL /**< A DMA request trigger transfer of a complete cycle. */ +} LDMA_CtrlReqMode_t; + +/** Source address increment unit size. */ +typedef enum +{ + ldmaCtrlSrcIncOne = _LDMA_CH_CTRL_SRCINC_ONE, /**< Increment source address by one unit data size. */ + ldmaCtrlSrcIncTwo = _LDMA_CH_CTRL_SRCINC_TWO, /**< Increment source address by two unit data sizes. */ + ldmaCtrlSrcIncFour = _LDMA_CH_CTRL_SRCINC_FOUR, /**< Increment source address by four unit data sizes. */ + ldmaCtrlSrcIncNone = _LDMA_CH_CTRL_SRCINC_NONE /**< Do not increment the source address. */ +} LDMA_CtrlSrcInc_t; + +/** DMA transfer unit size. */ +typedef enum +{ + ldmaCtrlSizeByte = _LDMA_CH_CTRL_SIZE_BYTE, /**< Each unit transfer is a byte. */ + ldmaCtrlSizeHalf = _LDMA_CH_CTRL_SIZE_HALFWORD, /**< Each unit transfer is a half-word. */ + ldmaCtrlSizeWord = _LDMA_CH_CTRL_SIZE_WORD /**< Each unit transfer is a word. */ +} LDMA_CtrlSize_t; + +/** Destination address increment unit size. */ +typedef enum +{ + ldmaCtrlDstIncOne = _LDMA_CH_CTRL_DSTINC_ONE, /**< Increment destination address by one unit data size. */ + ldmaCtrlDstIncTwo = _LDMA_CH_CTRL_DSTINC_TWO, /**< Increment destination address by two unit data sizes. */ + ldmaCtrlDstIncFour = _LDMA_CH_CTRL_DSTINC_FOUR, /**< Increment destination address by four unit data sizes. */ + ldmaCtrlDstIncNone = _LDMA_CH_CTRL_DSTINC_NONE /**< Do not increment the destination address. */ +} LDMA_CtrlDstInc_t; + +/** Source addressing mode. */ +typedef enum +{ + ldmaCtrlSrcAddrModeAbs = _LDMA_CH_CTRL_SRCMODE_ABSOLUTE, /**< Address fetched from a linked structure is absolute. */ + ldmaCtrlSrcAddrModeRel = _LDMA_CH_CTRL_SRCMODE_RELATIVE /**< Address fetched from a linked structure is relative. */ +} LDMA_CtrlSrcAddrMode_t; + +/** Destination addressing mode. */ +typedef enum +{ + ldmaCtrlDstAddrModeAbs = _LDMA_CH_CTRL_DSTMODE_ABSOLUTE, /**< Address fetched from a linked structure is absolute. */ + ldmaCtrlDstAddrModeRel = _LDMA_CH_CTRL_DSTMODE_RELATIVE /**< Address fetched from a linked structure is relative. */ +} LDMA_CtrlDstAddrMode_t; + +/** DMA linkload address mode. */ +typedef enum +{ + ldmaLinkModeAbs = _LDMA_CH_LINK_LINKMODE_ABSOLUTE, /**< Link address is an absolute address value. */ + ldmaLinkModeRel = _LDMA_CH_LINK_LINKMODE_RELATIVE /**< Link address is a two's complement releative address. */ +} LDMA_LinkMode_t; + +/** Insert extra arbitration slots to increase channel arbitration priority. */ +typedef enum +{ + ldmaCfgArbSlotsAs1 = _LDMA_CH_CFG_ARBSLOTS_ONE, /**< One arbitration slot selected. */ + ldmaCfgArbSlotsAs2 = _LDMA_CH_CFG_ARBSLOTS_TWO, /**< Two arbitration slots selected. */ + ldmaCfgArbSlotsAs4 = _LDMA_CH_CFG_ARBSLOTS_FOUR, /**< Four arbitration slots selected. */ + ldmaCfgArbSlotsAs8 = _LDMA_CH_CFG_ARBSLOTS_EIGHT /**< Eight arbitration slots selected. */ +} LDMA_CfgArbSlots_t; + +/** Source address increment sign. */ +typedef enum +{ + ldmaCfgSrcIncSignPos = _LDMA_CH_CFG_SRCINCSIGN_POSITIVE, /**< Increment source address. */ + ldmaCfgSrcIncSignNeg = _LDMA_CH_CFG_SRCINCSIGN_NEGATIVE /**< Decrement source address. */ +} LDMA_CfgSrcIncSign_t; + +/** Destination address increment sign. */ +typedef enum +{ + ldmaCfgDstIncSignPos = _LDMA_CH_CFG_DSTINCSIGN_POSITIVE, /**< Increment destination address. */ + ldmaCfgDstIncSignNeg = _LDMA_CH_CFG_DSTINCSIGN_NEGATIVE /**< Decrement destination address. */ +} LDMA_CfgDstIncSign_t; + +/** Peripherals that can trigger LDMA transfers. */ +typedef enum +{ + ldmaPeripheralSignal_NONE = LDMA_CH_REQSEL_SOURCESEL_NONE, ///< No peripheral selected for DMA triggering. + #if defined( LDMA_CH_REQSEL_SIGSEL_ADC0SCAN ) + ldmaPeripheralSignal_ADC0_SCAN = LDMA_CH_REQSEL_SIGSEL_ADC0SCAN | LDMA_CH_REQSEL_SOURCESEL_ADC0, ///< Trig on ADC0_SCAN. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_ADC0SINGLE ) + ldmaPeripheralSignal_ADC0_SINGLE = LDMA_CH_REQSEL_SIGSEL_ADC0SINGLE | LDMA_CH_REQSEL_SOURCESEL_ADC0, ///< Trig on ADC0_SINGLE. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_AGCRSSI ) + ldmaPeripheralSignal_AGC_RSSI = LDMA_CH_REQSEL_SIGSEL_AGCRSSI | LDMA_CH_REQSEL_SOURCESEL_AGC, ///< Trig on AGC_RSSI. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_CRYPTODATA0RD ) + ldmaPeripheralSignal_CRYPTO_DATA0RD = LDMA_CH_REQSEL_SIGSEL_CRYPTODATA0RD | LDMA_CH_REQSEL_SOURCESEL_CRYPTO, ///< Trig on CRYPTO_DATA0RD. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_CRYPTODATA0WR ) + ldmaPeripheralSignal_CRYPTO_DATA0WR = LDMA_CH_REQSEL_SIGSEL_CRYPTODATA0WR | LDMA_CH_REQSEL_SOURCESEL_CRYPTO, ///< Trig on CRYPTO_DATA0WR. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_CRYPTODATA0XWR ) + ldmaPeripheralSignal_CRYPTO_DATA0XWR = LDMA_CH_REQSEL_SIGSEL_CRYPTODATA0XWR | LDMA_CH_REQSEL_SOURCESEL_CRYPTO, ///< Trig on CRYPTO_DATA0XWR. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_CRYPTODATA1RD ) + ldmaPeripheralSignal_CRYPTO_DATA1RD = LDMA_CH_REQSEL_SIGSEL_CRYPTODATA1RD | LDMA_CH_REQSEL_SOURCESEL_CRYPTO, ///< Trig on CRYPTO_DATA1RD. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_CRYPTODATA1WR ) + ldmaPeripheralSignal_CRYPTO_DATA1WR = LDMA_CH_REQSEL_SIGSEL_CRYPTODATA1WR | LDMA_CH_REQSEL_SOURCESEL_CRYPTO, ///< Trig on CRYPTO_DATA1WR. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_I2C0RXDATAV ) + ldmaPeripheralSignal_I2C0_RXDATAV = LDMA_CH_REQSEL_SIGSEL_I2C0RXDATAV | LDMA_CH_REQSEL_SOURCESEL_I2C0, ///< Trig on I2C0_RXDATAV. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_I2C0TXBL ) + ldmaPeripheralSignal_I2C0_TXBL = LDMA_CH_REQSEL_SIGSEL_I2C0TXBL | LDMA_CH_REQSEL_SOURCESEL_I2C0, ///< Trig on I2C0_TXBL. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_LEUART0RXDATAV ) + ldmaPeripheralSignal_LEUART0_RXDATAV = LDMA_CH_REQSEL_SIGSEL_LEUART0RXDATAV | LDMA_CH_REQSEL_SOURCESEL_LEUART0, ///< Trig on LEUART0_RXDATAV. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_LEUART0TXBL ) + ldmaPeripheralSignal_LEUART0_TXBL = LDMA_CH_REQSEL_SIGSEL_LEUART0TXBL | LDMA_CH_REQSEL_SOURCESEL_LEUART0, ///< Trig on LEUART0_TXBL. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_LEUART0TXEMPTY ) + ldmaPeripheralSignal_LEUART0_TXEMPTY = LDMA_CH_REQSEL_SIGSEL_LEUART0TXEMPTY | LDMA_CH_REQSEL_SOURCESEL_LEUART0, ///< Trig on LEUART0_TXEMPTY. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_MODEMDEBUG ) + ldmaPeripheralSignal_MODEM_DEBUG = LDMA_CH_REQSEL_SIGSEL_MODEMDEBUG | LDMA_CH_REQSEL_SOURCESEL_MODEM, ///< Trig on MODEM_DEBUG. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_MSCWDATA ) + ldmaPeripheralSignal_MSC_WDATA = LDMA_CH_REQSEL_SIGSEL_MSCWDATA | LDMA_CH_REQSEL_SOURCESEL_MSC, ///< Trig on MSC_WDATA. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERBOF ) + ldmaPeripheralSignal_PROTIMER_BOF = LDMA_CH_REQSEL_SIGSEL_PROTIMERBOF | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_BOF. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERCC0 ) + ldmaPeripheralSignal_PROTIMER_CC0 = LDMA_CH_REQSEL_SIGSEL_PROTIMERCC0 | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_CC0. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERCC1 ) + ldmaPeripheralSignal_PROTIMER_CC1 = LDMA_CH_REQSEL_SIGSEL_PROTIMERCC1 | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_CC1. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERCC2 ) + ldmaPeripheralSignal_PROTIMER_CC2 = LDMA_CH_REQSEL_SIGSEL_PROTIMERCC2 | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_CC2. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERCC3 ) + ldmaPeripheralSignal_PROTIMER_CC3 = LDMA_CH_REQSEL_SIGSEL_PROTIMERCC3 | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_CC3. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERCC4 ) + ldmaPeripheralSignal_PROTIMER_CC4 = LDMA_CH_REQSEL_SIGSEL_PROTIMERCC4 | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_CC4. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERPOF ) + ldmaPeripheralSignal_PROTIMER_POF = LDMA_CH_REQSEL_SIGSEL_PROTIMERPOF | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_POF. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PROTIMERWOF ) + ldmaPeripheralSignal_PROTIMER_WOF = LDMA_CH_REQSEL_SIGSEL_PROTIMERWOF | LDMA_CH_REQSEL_SOURCESEL_PROTIMER, ///< Trig on PROTIMER_WOF. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PRSREQ0 ) + ldmaPeripheralSignal_PRS_REQ0 = LDMA_CH_REQSEL_SIGSEL_PRSREQ0 | LDMA_CH_REQSEL_SOURCESEL_PRS, ///< Trig on PRS_REQ0. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_PRSREQ1 ) + ldmaPeripheralSignal_PRS_REQ1 = LDMA_CH_REQSEL_SIGSEL_PRSREQ1 | LDMA_CH_REQSEL_SOURCESEL_PRS, ///< Trig on PRS_REQ1. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER0CC0 ) + ldmaPeripheralSignal_TIMER0_CC0 = LDMA_CH_REQSEL_SIGSEL_TIMER0CC0 | LDMA_CH_REQSEL_SOURCESEL_TIMER0, ///< Trig on TIMER0_CC0. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER0CC1 ) + ldmaPeripheralSignal_TIMER0_CC1 = LDMA_CH_REQSEL_SIGSEL_TIMER0CC1 | LDMA_CH_REQSEL_SOURCESEL_TIMER0, ///< Trig on TIMER0_CC1. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER0CC2 ) + ldmaPeripheralSignal_TIMER0_CC2 = LDMA_CH_REQSEL_SIGSEL_TIMER0CC2 | LDMA_CH_REQSEL_SOURCESEL_TIMER0, ///< Trig on TIMER0_CC2. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER0UFOF ) + ldmaPeripheralSignal_TIMER0_UFOF = LDMA_CH_REQSEL_SIGSEL_TIMER0UFOF | LDMA_CH_REQSEL_SOURCESEL_TIMER0, ///< Trig on TIMER0_UFOF. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER1CC0 ) + ldmaPeripheralSignal_TIMER1_CC0 = LDMA_CH_REQSEL_SIGSEL_TIMER1CC0 | LDMA_CH_REQSEL_SOURCESEL_TIMER1, ///< Trig on TIMER1_CC0. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER1CC1 ) + ldmaPeripheralSignal_TIMER1_CC1 = LDMA_CH_REQSEL_SIGSEL_TIMER1CC1 | LDMA_CH_REQSEL_SOURCESEL_TIMER1, ///< Trig on TIMER1_CC1. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER1CC2 ) + ldmaPeripheralSignal_TIMER1_CC2 = LDMA_CH_REQSEL_SIGSEL_TIMER1CC2 | LDMA_CH_REQSEL_SOURCESEL_TIMER1, ///< Trig on TIMER1_CC2. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER1CC3 ) + ldmaPeripheralSignal_TIMER1_CC3 = LDMA_CH_REQSEL_SIGSEL_TIMER1CC3 | LDMA_CH_REQSEL_SOURCESEL_TIMER1, ///< Trig on TIMER1_CC3. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_TIMER1UFOF ) + ldmaPeripheralSignal_TIMER1_UFOF = LDMA_CH_REQSEL_SIGSEL_TIMER1UFOF | LDMA_CH_REQSEL_SOURCESEL_TIMER1, ///< Trig on TIMER1_UFOF. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART0RXDATAV ) + ldmaPeripheralSignal_USART0_RXDATAV = LDMA_CH_REQSEL_SIGSEL_USART0RXDATAV | LDMA_CH_REQSEL_SOURCESEL_USART0, ///< Trig on USART0_RXDATAV. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART0TXBL ) + ldmaPeripheralSignal_USART0_TXBL = LDMA_CH_REQSEL_SIGSEL_USART0TXBL | LDMA_CH_REQSEL_SOURCESEL_USART0, ///< Trig on USART0_TXBL. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART0TXEMPTY ) + ldmaPeripheralSignal_USART0_TXEMPTY = LDMA_CH_REQSEL_SIGSEL_USART0TXEMPTY | LDMA_CH_REQSEL_SOURCESEL_USART0, ///< Trig on USART0_TXEMPTY. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART1RXDATAV ) + ldmaPeripheralSignal_USART1_RXDATAV = LDMA_CH_REQSEL_SIGSEL_USART1RXDATAV | LDMA_CH_REQSEL_SOURCESEL_USART1, ///< Trig on USART1_RXDATAV. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART1RXDATAVRIGHT ) + ldmaPeripheralSignal_USART1_RXDATAVRIGHT = LDMA_CH_REQSEL_SIGSEL_USART1RXDATAVRIGHT | LDMA_CH_REQSEL_SOURCESEL_USART1, ///< Trig on USART1_RXDATAVRIGHT. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART1TXBL ) + ldmaPeripheralSignal_USART1_TXBL = LDMA_CH_REQSEL_SIGSEL_USART1TXBL | LDMA_CH_REQSEL_SOURCESEL_USART1, ///< Trig on USART1_TXBL. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART1TXBLRIGHT ) + ldmaPeripheralSignal_USART1_TXBLRIGHT = LDMA_CH_REQSEL_SIGSEL_USART1TXBLRIGHT | LDMA_CH_REQSEL_SOURCESEL_USART1, ///< Trig on USART1_TXBLRIGHT. + #endif + #if defined( LDMA_CH_REQSEL_SIGSEL_USART1TXEMPTY ) + ldmaPeripheralSignal_USART1_TXEMPTY = LDMA_CH_REQSEL_SIGSEL_USART1TXEMPTY | LDMA_CH_REQSEL_SOURCESEL_USART1 ///< Trig on USART1_TXEMPTY. + #endif +} LDMA_PeripheralSignal_t; + + +/******************************************************************************* + ******************************* STRUCTS *********************************** + ******************************************************************************/ + +/** + * @brief + * DMA descriptor. + * @details + * The LDMA DMA controller supports three different DMA descriptors. Each + * consist of four WORD's which map directly onto hw control registers for a + * given DMA channel. The three descriptor types are XFER, SYNC and WRI. + * Refer to the reference manual for further information. + */ +typedef union +{ + /** + * TRANSFER DMA descriptor, this is the only descriptor type which can be + * used to start a DMA transfer. + */ + struct + { + uint32_t structType : 2; /**< Set to 0 to select XFER descriptor type. */ + uint32_t reserved0 : 1; + uint32_t structReq : 1; /**< DMA transfer trigger during LINKLOAD. */ + uint32_t xferCnt : 11; /**< Transfer count minus one. */ + uint32_t byteSwap : 1; /**< Enable byte swapping transfers. */ + uint32_t blockSize : 4; /**< Number of unit transfers per arb. cycle. */ + uint32_t doneIfs : 1; /**< Generate interrupt when done. */ + uint32_t reqMode : 1; /**< Block or cycle transfer selector. */ + uint32_t decLoopCnt : 1; /**< Enable looped transfers. */ + uint32_t ignoreSrec : 1; /**< Ignore single requests. */ + uint32_t srcInc : 2; /**< Source address increment unit size. */ + uint32_t size : 2; /**< DMA transfer unit size. */ + uint32_t dstInc : 2; /**< Destination address increment unit size. */ + uint32_t srcAddrMode: 1; /**< Source addressing mode. */ + uint32_t dstAddrMode: 1; /**< Destination addressing mode. */ + + uint32_t srcAddr; /**< DMA source address. */ + uint32_t dstAddr; /**< DMA destination address. */ + + uint32_t linkMode : 1; /**< Select absolute or relative link address.*/ + uint32_t link : 1; /**< Enable LINKLOAD when transfer is done. */ + int32_t linkAddr : 30; /**< Address of next (linked) descriptor. */ + } xfer; + + /** SYNCHRONIZE DMA descriptor, used for intra channel transfer + * syncronization. + */ + struct + { + uint32_t structType : 2; /**< Set to 1 to select SYNC descriptor type. */ + uint32_t reserved0 : 1; + uint32_t structReq : 1; /**< DMA transfer trigger during LINKLOAD. */ + uint32_t xferCnt : 11; /**< Transfer count minus one. */ + uint32_t byteSwap : 1; /**< Enable byte swapping transfers. */ + uint32_t blockSize : 4; /**< Number of unit transfers per arb. cycle. */ + uint32_t doneIfs : 1; /**< Generate interrupt when done. */ + uint32_t reqMode : 1; /**< Block or cycle transfer selector. */ + uint32_t decLoopCnt : 1; /**< Enable looped transfers. */ + uint32_t ignoreSrec : 1; /**< Ignore single requests. */ + uint32_t srcInc : 2; /**< Source address increment unit size. */ + uint32_t size : 2; /**< DMA transfer unit size. */ + uint32_t dstInc : 2; /**< Destination address increment unit size. */ + uint32_t srcAddrMode: 1; /**< Source addressing mode. */ + uint32_t dstAddrMode: 1; /**< Destination addressing mode. */ + + uint32_t syncSet : 8; /**< Set bits in LDMA_CTRL.SYNCTRIG register. */ + uint32_t syncClr : 8; /**< Clear bits in LDMA_CTRL.SYNCTRIG register*/ + uint32_t reserved3 : 16; + uint32_t matchVal : 8; /**< Sync trig match value. */ + uint32_t matchEn : 8; /**< Sync trig match enable. */ + uint32_t reserved4 : 16; + + uint32_t linkMode : 1; /**< Select absolute or relative link address.*/ + uint32_t link : 1; /**< Enable LINKLOAD when transfer is done. */ + int32_t linkAddr : 30; /**< Address of next (linked) descriptor. */ + } sync; + + /** WRITE DMA descriptor, used for write immediate operations. */ + struct + { + uint32_t structType : 2; /**< Set to 2 to select WRITE descriptor type.*/ + uint32_t reserved0 : 1; + uint32_t structReq : 1; /**< DMA transfer trigger during LINKLOAD. */ + uint32_t xferCnt : 11; /**< Transfer count minus one. */ + uint32_t byteSwap : 1; /**< Enable byte swapping transfers. */ + uint32_t blockSize : 4; /**< Number of unit transfers per arb. cycle. */ + uint32_t doneIfs : 1; /**< Generate interrupt when done. */ + uint32_t reqMode : 1; /**< Block or cycle transfer selector. */ + uint32_t decLoopCnt : 1; /**< Enable looped transfers. */ + uint32_t ignoreSrec : 1; /**< Ignore single requests. */ + uint32_t srcInc : 2; /**< Source address increment unit size. */ + uint32_t size : 2; /**< DMA transfer unit size. */ + uint32_t dstInc : 2; /**< Destination address increment unit size. */ + uint32_t srcAddrMode: 1; /**< Source addressing mode. */ + uint32_t dstAddrMode: 1; /**< Destination addressing mode. */ + + uint32_t immVal; /**< Data to be written at dstAddr. */ + uint32_t dstAddr; /**< DMA write destination address. */ + + uint32_t linkMode : 1; /**< Select absolute or relative link address.*/ + uint32_t link : 1; /**< Enable LINKLOAD when transfer is done. */ + int32_t linkAddr : 30; /**< Address of next (linked) descriptor. */ + } wri; +} LDMA_Descriptor_t; + +/** @brief LDMA initialization configuration structure. */ +typedef struct +{ + uint8_t ldmaInitCtrlNumFixed; /**< Arbitration mode separator.*/ + uint8_t ldmaInitCtrlSyncPrsClrEn; /**< PRS Synctrig clear enable. */ + uint8_t ldmaInitCtrlSyncPrsSetEn; /**< PRS Synctrig set enable. */ + uint8_t ldmaInitIrqPriority; /**< LDMA IRQ priority (0..7). */ +} LDMA_Init_t; + +/** + * @brief + * DMA transfer configuration structure. + * @details + * This struct configures all aspects of a DMA transfer. + */ +typedef struct +{ + uint32_t ldmaReqSel; /**< Selects DMA trigger source. */ + uint8_t ldmaCtrlSyncPrsClrOff; /**< PRS Synctrig clear enables to clear. */ + uint8_t ldmaCtrlSyncPrsClrOn; /**< PRS Synctrig clear enables to set. */ + uint8_t ldmaCtrlSyncPrsSetOff; /**< PRS Synctrig set enables to clear. */ + uint8_t ldmaCtrlSyncPrsSetOn; /**< PRS Synctrig set enables to set. */ + bool ldmaReqDis; /**< Mask the PRS trigger input. */ + bool ldmaDbgHalt; /**< Dis. DMA trig when cpu is halted. */ + uint8_t ldmaCfgArbSlots; /**< Arbitration slot number. */ + uint8_t ldmaCfgSrcIncSign; /**< Source addr. increment sign. */ + uint8_t ldmaCfgDstIncSign; /**< Dest. addr. increment sign. */ + uint8_t ldmaLoopCnt; /**< Counter for looped transfers. */ +} LDMA_TransferCfg_t; + + +/******************************************************************************* + ************************** STRUCT INITIALIZERS **************************** + ******************************************************************************/ + + +/** @brief Default DMA initialization structure. */ +#define LDMA_INIT_DEFAULT \ +{ \ + .ldmaInitCtrlNumFixed = _LDMA_CTRL_NUMFIXED_DEFAULT, /* Fixed priority arbitration. */ \ + .ldmaInitCtrlSyncPrsClrEn = 0, /* No PRS Synctrig clear enable*/ \ + .ldmaInitCtrlSyncPrsSetEn = 0, /* No PRS Synctrig set enable. */ \ + .ldmaInitIrqPriority = 3 /* IRQ priority level 3. */ \ +} + +/** + * @brief + * Generic DMA transfer configuration for memory to memory transfers. + */ +#define LDMA_TRANSFER_CFG_MEMORY() \ +{ \ + 0, 0, 0, 0, 0, \ + false, false, ldmaCfgArbSlotsAs1, \ + ldmaCfgSrcIncSignPos, ldmaCfgDstIncSignPos, 0 \ +} + +/** + * @brief + * Generic DMA transfer configuration for looped memory to memory transfers. + */ +#define LDMA_TRANSFER_CFG_MEMORY_LOOP( loopCnt) \ +{ \ + 0, 0, 0, 0, 0, \ + false, false, ldmaCfgArbSlotsAs1, \ + ldmaCfgSrcIncSignPos, ldmaCfgDstIncSignPos, \ + loopCnt \ +} + +/** + * @brief + * Generic DMA transfer configuration for memory to/from peripheral transfers. + */ +#define LDMA_TRANSFER_CFG_PERIPHERAL( signal ) \ +{ \ + signal, 0, 0, 0, 0, \ + false, false, ldmaCfgArbSlotsAs1, \ + ldmaCfgSrcIncSignPos, ldmaCfgDstIncSignPos, 0 \ +} + +/** + * @brief + * Generic DMA transfer configuration for looped memory to/from peripheral transfers. + */ +#define LDMA_TRANSFER_CFG_PERIPHERAL_LOOP( signal, loopCnt ) \ +{ \ + signal, 0, 0, 0, 0, \ + false, false, ldmaCfgArbSlotsAs1, \ + ldmaCfgSrcIncSignPos, ldmaCfgDstIncSignPos, loopCnt \ +} + +/** + * @brief + * DMA descriptor initializer for single memory to memory word transfer. + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of words to transfer. + */ +#define LDMA_DESCRIPTOR_SINGLE_M2M_WORD( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 1, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeWord, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = 0, \ + .link = 0, \ + .linkAddr = 0 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for single memory to memory half-word transfer. + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of half-words to transfer. + */ +#define LDMA_DESCRIPTOR_SINGLE_M2M_HALF( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 1, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeHalf, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = 0, \ + .link = 0, \ + .linkAddr = 0 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for single memory to memory byte transfer. + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of bytes to transfer. + */ +#define LDMA_DESCRIPTOR_SINGLE_M2M_BYTE( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 1, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeByte, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = 0, \ + .link = 0, \ + .linkAddr = 0 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for linked memory to memory word transfer. + * + * The link address must be an absolute address. + * @note + * The linkAddr member of the transfer descriptor is not + * initialized. + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of words to transfer. + */ +#define LDMA_DESCRIPTOR_LINKABS_M2M_WORD( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 0, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeWord, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeAbs, \ + .link = 1, \ + .linkAddr = 0 /* Must be set runtime ! */ \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for linked memory to memory half-word transfer. + * + * The link address must be an absolute address. + * @note + * The linkAddr member of the transfer descriptor is not + * initialized. + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of half-words to transfer. + */ +#define LDMA_DESCRIPTOR_LINKABS_M2M_HALF( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 0, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeHalf, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeAbs, \ + .link = 1, \ + .linkAddr = 0 /* Must be set runtime ! */ \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for linked memory to memory byte transfer. + * + * The link address must be an absolute address. + * @note + * The linkAddr member of the transfer descriptor is not + * initialized. + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of bytes to transfer. + */ +#define LDMA_DESCRIPTOR_LINKABS_M2M_BYTE( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 0, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeByte, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeAbs, \ + .link = 1, \ + .linkAddr = 0 /* Must be set runtime ! */ \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for linked memory to memory word transfer. + * + * The link address is a relative address. + * @note + * The linkAddr member of the transfer descriptor is + * initialized to 4, assuming that the next descriptor immediately follows + * this descriptor (in memory). + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of words to transfer. + * @param[in] linkjmp Address of descriptor to link to expressed as a + * signed number of descriptors from "here". + * 1=one descriptor forward in memory, + * 0=one this descriptor, + * -1=one descriptor back in memory. + */ +#define LDMA_DESCRIPTOR_LINKREL_M2M_WORD( src, dest, count, linkjmp ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 0, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeWord, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeRel, \ + .link = 1, \ + .linkAddr = ( linkjmp ) * 4 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for linked memory to memory half-word transfer. + * + * The link address is a relative address. + * @note + * The linkAddr member of the transfer descriptor is + * initialized to 4, assuming that the next descriptor immediately follows + * this descriptor (in memory). + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of half-words to transfer. + * @param[in] linkjmp Address of descriptor to link to expressed as a + * signed number of descriptors from "here". + * 1=one descriptor forward in memory, + * 0=one this descriptor, + * -1=one descriptor back in memory. + */ +#define LDMA_DESCRIPTOR_LINKREL_M2M_HALF( src, dest, count, linkjmp ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 0, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeHalf, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeRel, \ + .link = 1, \ + .linkAddr = ( linkjmp ) * 4 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for linked memory to memory byte transfer. + * + * The link address is a relative address. + * @note + * The linkAddr member of the transfer descriptor is + * initialized to 4, assuming that the next descriptor immediately follows + * this descriptor (in memory). + * @param[in] src Source data address. + * @param[in] dest Destination data address. + * @param[in] count Number of bytes to transfer. + * @param[in] linkjmp Address of descriptor to link to expressed as a + * signed number of descriptors from "here". + * 1=one descriptor forward in memory, + * 0=one this descriptor, + * -1=one descriptor back in memory. + */ +#define LDMA_DESCRIPTOR_LINKREL_M2M_BYTE( src, dest, count, linkjmp ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 1, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 0, \ + .reqMode = ldmaCtrlReqModeAll, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeByte, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeRel, \ + .link = 1, \ + .linkAddr = ( linkjmp ) * 4 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for byte transfers from a peripheral to memory. + * @param[in] src Peripheral data source register address. + * @param[in] dest Destination data address. + * @param[in] count Number of bytes to transfer. + */ +#define LDMA_DESCRIPTOR_SINGLE_P2M_BYTE( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 0, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 1, \ + .reqMode = ldmaCtrlReqModeBlock, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncNone, \ + .size = ldmaCtrlSizeByte, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = 0, \ + .link = 0, \ + .linkAddr = 0 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for byte transfers from memory to a peripheral + * @param[in] src Source data address. + * @param[in] dest Peripheral data register destination address. + * @param[in] count Number of bytes to transfer. + */ +#define LDMA_DESCRIPTOR_SINGLE_M2P_BYTE( src, dest, count ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 0, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 1, \ + .reqMode = ldmaCtrlReqModeBlock, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeByte, \ + .dstInc = ldmaCtrlDstIncNone, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = 0, \ + .link = 0, \ + .linkAddr = 0 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for byte transfers from a peripheral to memory. + * @param[in] src Peripheral data source register address. + * @param[in] dest Destination data address. + * @param[in] count Number of bytes to transfer. + * @param[in] linkjmp Address of descriptor to link to expressed as a + * signed number of descriptors from "here". + * 1=one descriptor forward in memory, + * 0=one this descriptor, + * -1=one descriptor back in memory. + */ +#define LDMA_DESCRIPTOR_LINKREL_P2M_BYTE( src, dest, count, linkjmp ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 0, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 1, \ + .reqMode = ldmaCtrlReqModeBlock, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncNone, \ + .size = ldmaCtrlSizeByte, \ + .dstInc = ldmaCtrlDstIncOne, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeRel, \ + .link = 1, \ + .linkAddr = ( linkjmp ) * 4 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for byte transfers from memory to a peripheral + * @param[in] src Source data address. + * @param[in] dest Peripheral data register destination address. + * @param[in] count Number of bytes to transfer. + * @param[in] linkjmp Address of descriptor to link to expressed as a + * signed number of descriptors from "here". + * 1=one descriptor forward in memory, + * 0=one this descriptor, + * -1=one descriptor back in memory. + */ +#define LDMA_DESCRIPTOR_LINKREL_M2P_BYTE( src, dest, count, linkjmp ) \ +{ \ + .xfer = \ + { \ + .structType = ldmaCtrlStructTypeXfer, \ + .structReq = 0, \ + .xferCnt = ( count ) - 1, \ + .byteSwap = 0, \ + .blockSize = ldmaCtrlBlockSizeUnit1, \ + .doneIfs = 1, \ + .reqMode = ldmaCtrlReqModeBlock, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = ldmaCtrlSrcIncOne, \ + .size = ldmaCtrlSizeByte, \ + .dstInc = ldmaCtrlDstIncNone, \ + .srcAddrMode = ldmaCtrlSrcAddrModeAbs, \ + .dstAddrMode = ldmaCtrlDstAddrModeAbs, \ + .srcAddr = (uint32_t)(src), \ + .dstAddr = (uint32_t)(dest), \ + .linkMode = ldmaLinkModeRel, \ + .link = 1, \ + .linkAddr = ( linkjmp ) * 4 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for Immediate WRITE transfer + * @param[in] value Immediate value to write. + * @param[in] address Write sddress. + */ +#define LDMA_DESCRIPTOR_SINGLE_WRITE( value, address ) \ +{ \ + .wri = \ + { \ + .structType = ldmaCtrlStructTypeWrite, \ + .structReq = 1, \ + .xferCnt = 0, \ + .byteSwap = 0, \ + .blockSize = 0, \ + .doneIfs = 1, \ + .reqMode = 0, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = 0, \ + .size = 0, \ + .dstInc = 0, \ + .srcAddrMode = 0, \ + .dstAddrMode = 0, \ + .immVal = (value), \ + .dstAddr = (uint32_t)(address), \ + .linkMode = 0, \ + .link = 0, \ + .linkAddr = 0 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for Immediate WRITE transfer + * + * The link address must be an absolute address. + * @note + * The linkAddr member of the transfer descriptor is not + * initialized. + * @param[in] value Immediate value to write. + * @param[in] address Write sddress. + */ +#define LDMA_DESCRIPTOR_LINKABS_WRITE( value, address ) \ +{ \ + .wri = \ + { \ + .structType = ldmaCtrlStructTypeWrite, \ + .structReq = 1, \ + .xferCnt = 0, \ + .byteSwap = 0, \ + .blockSize = 0, \ + .doneIfs = 0, \ + .reqMode = 0, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = 0, \ + .size = 0, \ + .dstInc = 0, \ + .srcAddrMode = 0, \ + .dstAddrMode = 0, \ + .immVal = (value), \ + .dstAddr = (uint32_t)(address), \ + .linkMode = ldmaLinkModeAbs, \ + .link = 1, \ + .linkAddr = 0 /* Must be set runtime ! */ \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for Immediate WRITE transfer + * @param[in] value Immediate value to write. + * @param[in] address Write sddress. + * @param[in] linkjmp Address of descriptor to link to expressed as a + * signed number of descriptors from "here". + * 1=one descriptor forward in memory, + * 0=one this descriptor, + * -1=one descriptor back in memory. + */ +#define LDMA_DESCRIPTOR_LINKREL_WRITE( value, address, linkjmp ) \ +{ \ + .wri = \ + { \ + .structType = ldmaCtrlStructTypeWrite, \ + .structReq = 1, \ + .xferCnt = 0, \ + .byteSwap = 0, \ + .blockSize = 0, \ + .doneIfs = 0, \ + .reqMode = 0, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = 0, \ + .size = 0, \ + .dstInc = 0, \ + .srcAddrMode = 0, \ + .dstAddrMode = 0, \ + .immVal = (value), \ + .dstAddr = (uint32_t)(address), \ + .linkMode = ldmaLinkModeRel, \ + .link = 1, \ + .linkAddr = ( linkjmp ) * 4 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for SYNC transfer + * @param[in] set Sync pattern bits to set. + * @param[in] clr Sync pattern bits to clear. + * @param[in] matchValue Sync pattern to match. + * @param[in] matchEnable Sync pattern bits to enable for match. + */ +#define LDMA_DESCRIPTOR_SINGLE_SYNC( set, clr, matchValue, matchEnable ) \ +{ \ + .sync = \ + { \ + .structType = ldmaCtrlStructTypeSync, \ + .structReq = 1, \ + .xferCnt = 0, \ + .byteSwap = 0, \ + .blockSize = 0, \ + .doneIfs = 1, \ + .reqMode = 0, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = 0, \ + .size = 0, \ + .dstInc = 0, \ + .srcAddrMode = 0, \ + .dstAddrMode = 0, \ + .syncSet = (set), \ + .syncClr = (clr), \ + .matchVal = (matchValue), \ + .matchEn = (matchEnable), \ + .linkMode = 0, \ + .link = 0, \ + .linkAddr = 0 \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for SYNC transfer + * + * The link address must be an absolute address. + * @note + * The linkAddr member of the transfer descriptor is not + * initialized. + * @param[in] set Sync pattern bits to set. + * @param[in] clr Sync pattern bits to clear. + * @param[in] matchValue Sync pattern to match. + * @param[in] matchEnable Sync pattern bits to enable for match. + */ +#define LDMA_DESCRIPTOR_LINKABS_SYNC( set, clr, matchValue, matchEnable ) \ +{ \ + .sync = \ + { \ + .structType = ldmaCtrlStructTypeSync, \ + .structReq = 1, \ + .xferCnt = 0, \ + .byteSwap = 0, \ + .blockSize = 0, \ + .doneIfs = 0, \ + .reqMode = 0, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = 0, \ + .size = 0, \ + .dstInc = 0, \ + .srcAddrMode = 0, \ + .dstAddrMode = 0, \ + .syncSet = (set), \ + .syncClr = (clr), \ + .matchVal = (matchValue), \ + .matchEn = (matchEnable), \ + .linkMode = ldmaLinkModeAbs, \ + .link = 1, \ + .linkAddr = 0 /* Must be set runtime ! */ \ + } \ +} + +/** + * @brief + * DMA descriptor initializer for SYNC transfer + * @param[in] set Sync pattern bits to set. + * @param[in] clr Sync pattern bits to clear. + * @param[in] matchValue Sync pattern to match. + * @param[in] matchEnable Sync pattern bits to enable for match. + * @param[in] linkjmp Address of descriptor to link to expressed as a + * signed number of descriptors from "here". + * 1=one descriptor forward in memory, + * 0=one this descriptor, + * -1=one descriptor back in memory. + */ +#define LDMA_DESCRIPTOR_LINKREL_SYNC( set, clr, matchValue, matchEnable, linkjmp ) \ +{ \ + .sync = \ + { \ + .structType = ldmaCtrlStructTypeSync, \ + .structReq = 1, \ + .xferCnt = 0, \ + .byteSwap = 0, \ + .blockSize = 0, \ + .doneIfs = 0, \ + .reqMode = 0, \ + .decLoopCnt = 0, \ + .ignoreSrec = 0, \ + .srcInc = 0, \ + .size = 0, \ + .dstInc = 0, \ + .srcAddrMode = 0, \ + .dstAddrMode = 0, \ + .syncSet = (set), \ + .syncClr = (clr), \ + .matchVal = (matchValue), \ + .matchEn = (matchEnable), \ + .linkMode = ldmaLinkModeRel, \ + .link = 1, \ + .linkAddr = ( linkjmp ) * 4 \ + } \ +} + +/******************************************************************************* + ***************************** PROTOTYPES ********************************** + ******************************************************************************/ + +void LDMA_DeInit( void ); +void LDMA_Init( LDMA_Init_t *init ); +void LDMA_StartTransfer( int ch, + LDMA_TransferCfg_t *transfer, + LDMA_Descriptor_t *descriptor ); +void LDMA_StopTransfer( int ch ); +bool LDMA_TransferDone( int ch ); +uint32_t LDMA_TransferRemainingCount( int ch ); + + +/***************************************************************************//** + * @brief + * Clear one or more pending LDMA interrupts. + * + * @param[in] flags + * Pending LDMA interrupt sources to clear. Use one or more valid + * interrupt flags for the LDMA module (LDMA_IFC_nnn). + ******************************************************************************/ +__STATIC_INLINE void LDMA_IntClear(uint32_t flags) +{ + LDMA->IFC = flags; +} + + +/***************************************************************************//** + * @brief + * Disable one or more LDMA interrupts. + * + * @param[in] flags + * LDMA interrupt sources to disable. Use one or more valid + * interrupt flags for the LDMA module (LDMA_IEN_nnn). + ******************************************************************************/ +__STATIC_INLINE void LDMA_IntDisable(uint32_t flags) +{ + LDMA->IEN &= ~flags; +} + + +/***************************************************************************//** + * @brief + * Enable one or more LDMA interrupts. + * + * @note + * Depending on the use, a pending interrupt may already be set prior to + * enabling the interrupt. Consider using LDMA_IntClear() prior to enabling + * if such a pending interrupt should be ignored. + * + * @param[in] flags + * LDMA interrupt sources to enable. Use one or more valid + * interrupt flags for the LDMA module (LDMA_IEN_nnn). + ******************************************************************************/ +__STATIC_INLINE void LDMA_IntEnable(uint32_t flags) +{ + LDMA->IEN |= flags; +} + + +/***************************************************************************//** + * @brief + * Get pending LDMA interrupt flags. + * + * @note + * The event bits are not cleared by the use of this function. + * + * @return + * LDMA interrupt sources pending. Returns one or more valid + * interrupt flags for the LDMA module (LDMA_IF_nnn). + ******************************************************************************/ +__STATIC_INLINE uint32_t LDMA_IntGet(void) +{ + return LDMA->IF; +} + + +/***************************************************************************//** + * @brief + * Get enabled and pending LDMA interrupt flags. + * Useful for handling more interrupt sources in the same interrupt handler. + * + * @note + * Interrupt flags are not cleared by the use of this function. + * + * @return + * Pending and enabled LDMA interrupt sources + * The return value is the bitwise AND of + * - the enabled interrupt sources in LDMA_IEN and + * - the pending interrupt flags LDMA_IF + ******************************************************************************/ +__STATIC_INLINE uint32_t LDMA_IntGetEnabled(void) +{ + uint32_t ien; + + ien = LDMA->IEN; + return LDMA->IF & ien; +} + + +/***************************************************************************//** + * @brief + * Set one or more pending LDMA interrupts + * + * @param[in] flags + * LDMA interrupt sources to set to pending. Use one or more valid + * interrupt flags for the LDMA module (LDMA_IFS_nnn). + ******************************************************************************/ +__STATIC_INLINE void LDMA_IntSet(uint32_t flags) +{ + LDMA->IFS = flags; +} + +/** @} (end addtogroup LDMA) */ +/** @} (end addtogroup EM_Library) */ + +#ifdef __cplusplus +} +#endif + +#endif /* defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 ) */ +#endif /* __SILICON_LABS_EM_LDMA_H__ */