/******************************************************************************* | |
* (c) Copyright 2008 Actel Corporation. All rights reserved. | |
* | |
* SmartFusion microcontroller subsystem Peripheral DMA bare metal software | |
* driver public API. | |
* | |
* SVN $Revision: 2110 $ | |
* SVN $Date: 2010-02-05 15:24:19 +0000 (Fri, 05 Feb 2010) $ | |
*/ | |
/*=========================================================================*//** | |
@mainpage SmartFusion MSS GPIO Bare Metal Driver. | |
@section intro_sec Introduction | |
The SmartFusion Microcontroller Subsystem (MSS) includes an 8 channel | |
Peripheral DMA (PDMA) controller. | |
This software driver provides a set of functions for controlling the MSS PDMA | |
controller as part of a bare metal system where no operating system is available. | |
This driver can be adapted for use as part of an operating system but the | |
implementation of the adaptation layer between this driver and the operating | |
system's driver model is outside the scope of this driver. | |
@section theory_op Theory of Operation | |
The MSS PDMA driver uses the SmartFusion "Cortex Microcontroler Software | |
Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access MSS hardware | |
registers. You must ensure that the SmartFusion CMSIS-PAL is either included | |
in the software toolchain used to build your project or is included in your | |
project. The most up-to-date SmartFusion CMSIS-PAL files can be obtained using | |
the Actel Firmware Catalog. | |
The MSS PDMA driver functions are grouped into the following categories: | |
- Initialization | |
- Configuration | |
- DMA transfer control | |
- Interrupt control | |
The MSS PDMA driver is initialized through a call to the PDMA_init() function. | |
The PDMA_init() function must be called before any other PDMA driver functions | |
can be called. | |
Each PDMA channel is individually configured through a call to the PDMA_configure() | |
function. Configuration includes: | |
- channel priority | |
- transfer size | |
- source and/or destination address increment | |
- source or destination of the DMA transfer | |
PDMA channels can be divided into high and low priority channels. High priority | |
channels are given more opportunities to perform transfers than low priority | |
channels when there are continuous high priority channels requests. The ratio | |
of high priority to low priority PDMA transfers is configurable through the | |
PDMA_set_priority() function. | |
PDMA channels can be configured to perform byte (8 bits), half-word (16 bits) | |
or word (32 bits) transfers. | |
The source and destination address of a PDMA channels transfers can be | |
independently configured to increment by 0, 1, 2 or 4 bytes. For example, the | |
content of a byte buffer located in RAM can be transferred into a peripherals | |
transmit register by configuring the source address increment to one byte and | |
no increment of the destination address. | |
The source or destination of a PDMA channels transfers can be configured to | |
be one of the MSS peripherals. This allows the PDMA controller to use some | |
hardware flow control signaling with the peripheral to avoid overrunning the | |
peripherals data buffer when the peripheral is the destination of the DMA | |
transfer, or attempting to read data from the peripheral while it is not ready | |
when the peripheral is the source of the transfer. | |
A PDMA channel can also be configured to transfer data between two memory | |
mapped locations (memory to memory). No hardware flow control is used by the | |
PDMA controller for data transfer in this configuration. | |
A DMA transfer can be initiated by a call to the PDMA_start() function after a | |
PDMA channel has been configured. Once started, further data can be pushed | |
through the PDMA channel by calling the PDMA_load_next_buffer() function. The | |
PDMA_load_next_buffer() function can be called every time a call to the | |
PDMA_status() function indicates that the PDMA channel used for the transfer | |
has a free buffer or it can be called as a result of a PDMA interrupt. | |
A DMA transfer can be paused and resumed through calls to functions PDMA_pause() | |
and PDMA_resume(). | |
Your application can manage DMA transfers using interrupts through the use of | |
the following functions: | |
- PDMA_set_irq_handler() | |
- PDMA_enable_irq() | |
- PDMA_clear_irq() | |
- PDMA_disable_irq() | |
The PDMA_set_irq_handler() function is used to register PDMA channel interrupt | |
handler functions with the driver. You must create and register an interrupt | |
handler function for each interrupt driven PDMA channel used by the application. | |
Use the PDMA_enable_irq() function to enable interrupts for the PDMA channels. | |
Every time a PDMA channel completes the transfer of a buffer it causes a PDMA | |
interrupt to occur and the PDMA driver will call the interrupt handler | |
registered by the application for that PDMA channel. | |
*//*=========================================================================*/ | |
#ifndef __MSS_PERIPHERAL_DMA_H_ | |
#define __MSS_PERIPHERAL_DMA_H_ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
#include "../../CMSIS/a2fxxxm3.h" | |
/***************************************************************************//** | |
The pdma_channel_id_t enumeration is used to identify peripheral DMA channels. | |
It is used as function parameter to specify the PDMA channel used. | |
*/ | |
typedef enum __pdma_channel_id | |
{ | |
PDMA_CHANNEL_0 = 0, | |
PDMA_CHANNEL_1, | |
PDMA_CHANNEL_2, | |
PDMA_CHANNEL_3, | |
PDMA_CHANNEL_4, | |
PDMA_CHANNEL_5, | |
PDMA_CHANNEL_6, | |
PDMA_CHANNEL_7 | |
} pdma_channel_id_t; | |
/***************************************************************************//** | |
The pdma_src_dest_t enumeration is used to specify the source or destination | |
of transfers on a PDMA channel. It specifies which hardware peripheral will be | |
the source or destination of DMA transfers. This allows the PDMA controller | |
to use hardware flow control signals to avoid overrunning a | |
destination peripheral with data it is not ready to receive, or attempting to | |
transfer data from a peripheral while it has no data ready to transfer. | |
The pdma_src_dest_t enumeration can also be used to specify that a PDMA channel | |
is configured to transfer data between two memory mapped locations | |
(memory to memory). No hardware data flow control is used by the PDMA | |
controller in this configuration. | |
This enumeration is used as parameter to function PDMA_configure(). | |
*/ | |
typedef enum __pdma_src_dest | |
{ | |
PDMA_FROM_UART_0 = 0, | |
PDMA_TO_UART_0, | |
PDMA_FROM_UART_1, | |
PDMA_TO_UART_1, | |
PDMA_FROM_SPI_0, | |
PDMA_TO_SPI_0, | |
PDMA_FROM_SPI_1, | |
PDMA_TO_SPI_1, | |
PDMA_FROM_FPGA_1, | |
PDMA_TO_FPGA_1, | |
PDMA_FROM_FPGA_0, | |
PDMA_TO_FPGA_0, | |
PDMA_TO_ACE, | |
PDMA_FROM_ACE, | |
PDMA_MEM_TO_MEM | |
} pdma_src_dest_t; | |
/***************************************************************************//** | |
The pdma_priority_ratio_t enumeration is used to configure the ratio of high | |
priority to low priority PDMA channels. This ratio specifies how many DMA | |
transfer opportunities will be given to high priority channels before a DMA | |
transfer opportunity is given to a low priority channel when there are | |
continuous requests from high priority channels. This enumeration is used as | |
parameter to function PDMA_set_priority_ratio(). | |
*/ | |
typedef enum __pdma_priority_ratio_t | |
{ | |
PDMA_ROUND_ROBIN = 0, | |
PDMA_RATIO_HIGH_LOW_1_TO_1 = 1, | |
PDMA_RATIO_HIGH_LOW_3_TO_1 = 3, | |
PDMA_RATIO_HIGH_LOW_7_TO_1 = 7, | |
PDMA_RATIO_HIGH_LOW_15_TO_1 = 15, | |
PDMA_RATIO_HIGH_LOW_31_TO_1 = 31, | |
PDMA_RATIO_HIGH_LOW_63_TO_1 = 63, | |
PDMA_RATIO_HIGH_LOW_127_TO_1 = 127, | |
PDMA_RATIO_HIGH_LOW_255_TO_1 = 255 | |
} pdma_priority_ratio_t; | |
/***************************************************************************//** | |
The pdma_channel_isr_t type is a pointer to a PDMA channel interrupt handler | |
function. It specifies the function prototype of functions that can be | |
registered as PDMA channel interrupt handlers. It is used as parameter to | |
function PDMA_set_irq_handler(). | |
*/ | |
typedef void (*pdma_channel_isr_t)( void ); | |
/***************************************************************************//** | |
These constants are used to build the channel_cfg parameter of the | |
PDMA_configure() function. They specify whether a channel is a high or low | |
priority channel. | |
*/ | |
#define PDMA_LOW_PRIORITY 0x0000 | |
#define PDMA_HIGH_PRIORITY 0x0200 | |
/***************************************************************************//** | |
These constants are used to build the channel_cfg parameter of the | |
PDMA_configure() function. They specify the data width of the transfers | |
performed by a PDMA channel. | |
*/ | |
#define PDMA_BYTE_TRANSFER 0x0000 /* Byte transfers (8 bits) */ | |
#define PDMA_HALFWORD_TRANSFER 0x0004 /* Half-word transfers (16 bits) */ | |
#define PDMA_WORD_TRANSFER 0x0008 /* Word transfers (32 bits) */ | |
/***************************************************************************//** | |
These constants are used to build the channel_cfg parameter of the | |
PDMA_configure() function. They specify the PDMA channels source and | |
destination address increment. | |
*/ | |
#define PDMA_NO_INC 0 | |
#define PDMA_INC_SRC_ONE_BYTE 0x0400 | |
#define PDMA_INC_SRC_TWO_BYTES 0x0800 | |
#define PDMA_INC_SRC_FOUR_BYTES 0x0C00 | |
#define PDMA_INC_DEST_ONE_BYTE 0x1000 | |
#define PDMA_INC_DEST_TWO_BYTES 0x2000 | |
#define PDMA_INC_DEST_FOUR_BYTES 0x3000 | |
/***************************************************************************//** | |
* Mask for various control register bits. | |
*/ | |
#define PDMA_IRQ_ENABLE_MASK (uint32_t)0x00000040 | |
#define PDMA_PAUSE_MASK (uint32_t)0x00000010 | |
/***************************************************************************//** | |
These constants are used to specify the src_addr parameter to the PDMA_start() | |
and PDMA_load_next_buffer() functions. They specify the receive register | |
address of peripherals that can be the source of a DMA transfer. | |
When a PDMA channel is configured for DMA transfers from a peripheral to memory, | |
the constant specifying that peripherals receive register address must be used | |
as the src_addr parameter. | |
*/ | |
#define PDMA_SPI0_RX_REGISTER 0x40001010uL | |
#define PDMA_SPI1_RX_REGISTER 0x40011010uL | |
#define PDMA_UART0_RX_REGISTER 0x40000000uL | |
#define PDMA_UART1_RX_REGISTER 0x40010000uL | |
#define PDMA_ACE_PPE_DATAOUT 0x40021308uL | |
/***************************************************************************//** | |
These constants are used to specify the dest_addr parameter to the PDMA_start() | |
and PDMA_load_next_buffer() functions. They specify the transmit register | |
address of peripherals that can be the destination of a DMA transfer. | |
When a PDMA channel is configured for DMA transfers from memory to a peripheral, | |
the constant specifying that peripherals transmit register address must be used | |
as the dest_addr parameter. | |
*/ | |
#define PDMA_SPI0_TX_REGISTER 0x40001014uL | |
#define PDMA_SPI1_TX_REGISTER 0x40011014uL | |
#define PDMA_UART0_TX_REGISTER 0x40000000uL | |
#define PDMA_UART1_TX_REGISTER 0x40010000uL | |
#define PDMA_ACE_SSE_DATAIN 0x40020700uL | |
/***************************************************************************//** | |
The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value for the | |
PDMA_configure() function write_adjust parameter. | |
*/ | |
#define PDMA_DEFAULT_WRITE_ADJ 10u | |
/***************************************************************************//** | |
The PDMA_init() function initializes the peripheral DMA hardware and driver | |
internal data. It resets the PDMA and it also clears any pending PDMA | |
interrupts in the Cortex-M3 interrupt controller. When the function exits, it | |
takes the PDMA block out of reset. | |
*/ | |
void PDMA_init( void ); | |
/***************************************************************************//** | |
The PDMA_configure() function configures a PDMA channel. | |
It specifies: | |
- The peripheral which will be the source or destination of the DMA transfer. | |
- Whether the DMA channel will be a high or low priority channel | |
- The source and destination address increment that will take place after | |
each transfer. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
@param src_dest | |
The src_dest parameter specifies the source or destination of the DMA | |
transfers that will be performed. It can be one of the following: | |
- PDMA_FROM_UART_0 | |
- PDMA_TO_UART_0 | |
- PDMA_FROM_UART_1 | |
- PDMA_TO_UART_1 | |
- PDMA_FROM_SPI_0 | |
- PDMA_TO_SPI_0 | |
- PDMA_FROM_SPI_1 | |
- PDMA_TO_SPI_1 | |
- PDMA_FROM_FPGA_1 | |
- PDMA_TO_FPGA_1 | |
- PDMA_FROM_FPGA_0 | |
- PDMA_TO_FPGA_0 | |
- PDMA_TO_ACE | |
- PDMA_FROM_ACE | |
- PDMA_MEM_TO_MEM | |
@param channel_cfg | |
The channel_cfg parameter specifies the configuration of the PDMA channel. | |
The configuration includes: | |
- channel priority | |
- transfer size | |
- source and/or destination address increment | |
The channel_cfg parameter value is a logical OR of: | |
One of the following to specify the channel priority: | |
- PDMA_LOW_PRIORITY | |
- PDMA_HIGH_PRIORITY | |
One of the following to specify the transfer size: | |
- PDMA_BYTE_TRANSFER | |
- PDMA_HALFWORD_TRANSFER | |
- PDMA_WORD_TRANSFER | |
One or two of the following to specify the source and/or destination address | |
increment: | |
- PDMA_NO_INC | |
- PDMA_INC_SRC_ONE_BYTE | |
- PDMA_INC_SRC_TWO_BYTES | |
- PDMA_INC_SRC_FOUR_BYTES | |
- PDMA_INC_DEST_ONE_BYTE | |
- PDMA_INC_DEST_TWO_BYTES | |
- PDMA_INC_DEST_FOUR_BYTES | |
@param write_adjust | |
The write_adjust parameter specifies the number of Cortex-M3 clock cycles | |
the PDMA controller will wait before attempting another transfer cycle. This | |
delay is necessary when peripherals are used as destination of a DMA transfer | |
to ensure the DMA controller interprets the state of the peripherals ready | |
signal only after data has actually been written to the peripheral. This delay | |
accounts for posted writes (dump and run) for write accesses to peripherals. | |
The effect of posted writes is that if the PDMA performs a write operation to | |
a peripheral, the data is not actually written into the peripheral until | |
sometime after the PDMA controller thinks it is written. | |
A suitable value for write_adjust depends on the target of the DMA transfer. | |
Guidelines for choosing this value are as follows: | |
The PDMA_DEFAULT_WRITE_ADJ constant provides a suitable default value | |
for the write_adjust parameter when the PDMA channel is configured for | |
transfers with MSS peripherals. | |
The PDMA_DEFAULT_WRITE_ADJ constant can also be used for DMA transfers | |
with FPGA fabric implemented peripherals making use of the DMAREADY0 or | |
DMAREADY1fabric interface signal to indicate that the peripheral is | |
ready for another DMA transfer. | |
The write_adjust parameter can be set to zero to achieve maximum transfer | |
speed for genuine memory to memory transfers. | |
The internal latency of FPGA implemented peripherals will decide the | |
write_adjust value for fabric peripherals that do not use the DMAREADY0 | |
or DMAREADY1 fabric interface signals. You need to check the fabric | |
peripheral documentation for the value to use. | |
Example: | |
@code | |
PDMA_configure | |
( | |
PDMA_CHANNEL_0, | |
PDMA_TO_SPI_1, | |
PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE, | |
PDMA_DEFAULT_WRITE_ADJ | |
); | |
@endcode | |
*/ | |
void PDMA_configure | |
( | |
pdma_channel_id_t channel_id, | |
pdma_src_dest_t src_dest, | |
uint32_t channel_cfg, | |
uint8_t write_adjust | |
); | |
/***************************************************************************//** | |
The PDMA_set_priority_ratio() function sets the ratio of high priority to low | |
priority DMA access opportunities. This ratio is used by the PDMA controller | |
arbiter to decide which PDMA channel will be given the opportunity to perform | |
a transfer when multiple PDMA channels are requesting to transfer data at the | |
same time. The priority ratio specifies how many DMA transfer opportunities | |
will be given to high priority channels before a DMA transfer opportunity is | |
given to a low priority channel when there are continuous requests from high | |
priority channels. | |
@param priority_ratio | |
The priority_ratio parameter specifies the ratio of DMA access opportunities | |
given to high priority channels versus low priority channels. | |
Allowed values for this parameter are: | |
- PDMA_ROUND_ROBIN | |
- PDMA_RATIO_HIGH_LOW_1_TO_1 | |
- PDMA_RATIO_HIGH_LOW_3_TO_1 | |
- PDMA_RATIO_HIGH_LOW_7_TO_1 | |
- PDMA_RATIO_HIGH_LOW_15_TO_1 | |
- PDMA_RATIO_HIGH_LOW_31_TO_1 | |
- PDMA_RATIO_HIGH_LOW_63_TO_1 | |
- PDMA_RATIO_HIGH_LOW_127_TO_1 | |
- PDMA_RATIO_HIGH_LOW_255_TO_1 | |
Example: | |
@code | |
PDMA_set_priority_ratio( PDMA_ROUND_ROBIN ); | |
@endcode | |
*/ | |
static __INLINE void PDMA_set_priority_ratio | |
( | |
pdma_priority_ratio_t priority_ratio | |
) | |
{ | |
PDMA->RATIO_HIGH_LOW = (uint32_t)priority_ratio; | |
} | |
/***************************************************************************//** | |
The PDMA_start() function initiates a DMA transfer. It specifies the source | |
and destination address of the transfer as well as the number of transfers | |
that must take place. The source and destination addresses can be the address | |
of peripheral registers. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
@param src_addr | |
The src_addr parameter specifies the address location of the data to be | |
transferred. You must ensure that this source address is consistent with the | |
DMA source configured for the selected channel using the PDMA_configure() | |
function. | |
For DMA transfers from MSS peripheral to memory, the following src_addr | |
parameter values are allowed: | |
PDMA_SPI0_RX_REGISTER | |
PDMA_SPI1_RX_REGISTER | |
PDMA_UART0_RX_REGISTER | |
PDMA_UART1_RX_REGISTER | |
PDMA_ACE_PPE_DATAOUT | |
For DMA transfers from FPGA fabric peripheral to memory, the following | |
src_addr parameter values are allowed: | |
An address in the FPGA fabric address space (0x40050000-0x400FFFFF) | |
For DMA transfers from memory to MSS peripheral, or from memory to FPGA | |
fabric peripheral, or from memory to memory, the following src_addr | |
parameter values are allowed: | |
Any memory mapped address. | |
@param dest_addr | |
The dest_addr parameter specifies the destination address of the PDMA | |
transfer. You must ensure that this matches with the DMA destination | |
configured for the selected channel. | |
For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed: | |
PDMA_SPI0_TX_REGISTER | |
PDMA_SPI1_TX_REGISTER | |
PDMA_UART0_TX_REGISTER | |
PDMA_UART1_TX_REGISTER | |
PDMA_ACE_SSE_DATAIN | |
For DMA transfers from memory to FPGA fabric peripheral, the following | |
dest_addr parameter values are allowed: | |
An address in the FPGA fabric address space (0x40050000-0x400FFFFF) | |
For DMA transfers from MSS peripheral to memory, or from FPGA fabric | |
peripheral to memory, or from memory to memory, the following dest_addr | |
parameter values are allowed: | |
Any memory mapped address. | |
@param transfer_count | |
The transfer_count parameter specifies the number of transfers to be | |
performed. It is the number of bytes to transfer if the PDMA channel is | |
configured for byte transfer, the number of half-words to transfer if the | |
PDMA channel is configured for half-word transfer, or the number of words | |
to transfer if the PDMA channel is configured for word transfer. | |
Example: | |
@code | |
PDMA_start | |
( | |
PDMA_CHANNEL_3, | |
PDMA_SPI1_RX_REGISTER, | |
(uint32_t)slave_rx_buffer, | |
sizeof(slave_rx_buffer) | |
); | |
@endcode | |
*/ | |
void PDMA_start | |
( | |
pdma_channel_id_t channel_id, | |
uint32_t src_addr, | |
uint32_t dest_addr, | |
uint16_t transfer_count | |
); | |
/***************************************************************************//** | |
The PDMA_load_next_buffer() function sets the next buffer to be transferred. | |
This function is called after a transfer has been initiated using the | |
PDMA_start() function. Its purpose is to keep feeding a PDMA channel with data | |
buffers. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
@param src_addr | |
The src_addr parameter specifies the address location of the data to be | |
transferred. You must ensure that this source address is consistent with the | |
DMA source configured for the selected channel using the PDMA_configure() | |
function. | |
For DMA transfers from MSS peripheral to memory, the following src_addr parameter values are allowed: | |
PDMA_SPI0_RX_REGISTER | |
PDMA_SPI1_RX_REGISTER | |
PDMA_UART0_RX_REGISTER | |
PDMA_UART1_RX_REGISTER | |
PDMA_ACE_PPE_DATAOUT | |
For DMA transfers from FPGA fabric peripheral to memory, the following src_addr parameter values are allowed: | |
An address in the FPGA fabric address space (0x40050000-0x400FFFFF) | |
For DMA transfers from memory to MSS peripheral, or from memory to FPGA fabric peripheral, or from memory to memory, the following src_addr parameter values are allowed: | |
Any memory mapped address. | |
@param dest_addr | |
The dest_addr parameter specifies the destination address of the PDMA | |
transfer. You must ensure that this matches with the DMA destination | |
configured for the selected channel. | |
For DMA transfers from memory to MSS peripheral, the following dest_addr parameter values are allowed: | |
PDMA_SPI0_TX_REGISTER | |
PDMA_SPI1_TX_REGISTER | |
PDMA_UART0_TX_REGISTER | |
PDMA_UART1_TX_REGISTER | |
PDMA_ACE_SSE_DATAIN | |
For DMA transfers from memory to FPGA fabric peripheral, the following dest_addr parameter values are allowed: | |
An address in the FPGA fabric address space (0x40050000-0x400FFFFF) | |
For DMA transfers from MSS peripheral to memory, or from FPGA fabric peripheral to memory, or from memory to memory, the following dest_addr parameter values are allowed: | |
Any memory mapped address. | |
@param transfer_count | |
The transfer_count parameter specifies the number of transfers to be | |
performed. It is the number of bytes to transfer if the PDMA channel is | |
configured for byte transfer, the number of half-words to transfer if the | |
PDMA channel is configured for half-word transfer or the number of words to | |
transfer if the PDMA channel is configured for word transfer. | |
Example: | |
@code | |
void write_cmd_data | |
( | |
mss_spi_instance_t * this_spi, | |
const uint8_t * cmd_buffer, | |
uint16_t cmd_byte_size, | |
uint8_t * data_buffer, | |
uint16_t data_byte_size | |
) | |
{ | |
uint32_t transfer_size; | |
transfer_size = cmd_byte_size + data_byte_size; | |
MSS_SPI_disable( this_spi ); | |
MSS_SPI_set_transfer_byte_count( this_spi, transfer_size ); | |
PDMA_start | |
( | |
PDMA_CHANNEL_0, | |
(uint32_t)cmd_buffer, | |
PDMA_SPI1_TX_REGISTER, | |
cmd_byte_size | |
); | |
PDMA_load_next_buffer | |
( | |
PDMA_CHANNEL_0, | |
(uint32_t)data_buffer, | |
PDMA_SPI1_TX_REGISTER, | |
data_byte_size | |
); | |
MSS_SPI_enable( this_spi ); | |
while ( !MSS_SPI_tx_done(this_spi) ) | |
{ | |
; | |
} | |
} | |
@endcode | |
*/ | |
void PDMA_load_next_buffer | |
( | |
pdma_channel_id_t channel_id, | |
uint32_t src_addr, | |
uint32_t dest_addr, | |
uint16_t transfer_count | |
); | |
/***************************************************************************//** | |
The PDMA_status() function returns the status of a DMA channel. | |
The returned value indicates if transfers have been completed using buffer A | |
or buffer B of the PDMA hardware block. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
@return | |
bit 0 of the return value indicates if buffer A has been trasnfered. It is | |
set to 1 if the transfer has completed. | |
bit 1 of the return value indicates if buffer B has been transfered. It is | |
set to 1 if the transfer has completed. | |
*/ | |
uint32_t PDMA_status | |
( | |
pdma_channel_id_t channel_id | |
); | |
/***************************************************************************//** | |
The PDMA_pause() function temporarily pauses a PDMA transfer taking place on | |
the specified PDMA channel. The transfer can later be resumed by using the | |
PDMA_resume() function. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
*/ | |
static __INLINE void PDMA_pause( pdma_channel_id_t channel_id ) | |
{ | |
PDMA->CHANNEL[channel_id].CRTL |= PDMA_PAUSE_MASK; | |
} | |
/***************************************************************************//** | |
The PDMA_resume() function resumes a transfer previously paused using the | |
PDMA_pause() function. | |
@param channel_id The channel_id parameter identifies the PDMA channel | |
used by the function. | |
*/ | |
static __INLINE void PDMA_resume( pdma_channel_id_t channel_id ) | |
{ | |
PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_PAUSE_MASK; | |
} | |
/***************************************************************************//** | |
The PDMA_enable_irq() enables the PDMA hardware to generate an interrupt when | |
a DMA transfer completes on the specified PDMA channel. This function also | |
enables the PDMA interrupt in the Cortex-M3 interrupt controller. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
*/ | |
void PDMA_enable_irq( pdma_channel_id_t channel_id ); | |
/***************************************************************************//** | |
The PDMA_disable_irq() disables interrupts for a specific PDMA channel. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
*/ | |
static __INLINE void PDMA_disable_irq( pdma_channel_id_t channel_id ) | |
{ | |
PDMA->CHANNEL[channel_id].CRTL &= ~PDMA_IRQ_ENABLE_MASK; | |
} | |
/***************************************************************************//** | |
The PDMA_set_irq_handler() function registers a handler function for | |
interrupts generated on the completion of a transfer on a specific PDMA | |
channel. This function also enables the PDMA interrupt both in the PDMA | |
controller and in the Cortex-M3 interrupt controller. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
@param handler | |
The handler parameter is a pointer to the function that will be called when | |
a transfer completes on the PDMA channel identified by channel_id and the | |
interrupt is enabled for that channel. | |
Example: | |
@code | |
void slave_dma_irq_handler( void ) | |
{ | |
if ( g_spi1_rx_buffer[2] == 0x99 ) | |
{ | |
PDMA_load_next_buffer | |
( | |
PDMA_CHANNEL_0, | |
(uint32_t)g_spi1_tx_buffer_b, | |
PDMA_SPI1_TX_REGISTER, | |
sizeof(g_spi1_tx_buffer_b) | |
); | |
} | |
PDMA_disable_irq( PDMA_CHANNEL_3 ); | |
} | |
void setup_dma( void ) | |
{ | |
PDMA_init(); | |
PDMA_configure | |
( | |
PDMA_CHANNEL_0, | |
PDMA_TO_SPI_1, | |
PDMA_LOW_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_SRC_ONE_BYTE | |
); | |
PDMA_configure | |
( | |
PDMA_CHANNEL_3, | |
PDMA_FROM_SPI_1, | |
PDMA_HIGH_PRIORITY | PDMA_BYTE_TRANSFER | PDMA_INC_DEST_ONE_BYTE | |
); | |
PDMA_set_irq_handler( PDMA_CHANNEL_3, slave_dma_irq_handler ); | |
PDMA_start( PDMA_CHANNEL_3, PDMA_SPI1_RX_REGISTER, (uint32_t)g_spi1_rx_buffer, 3 ); | |
} | |
@endcode | |
*/ | |
void PDMA_set_irq_handler | |
( | |
pdma_channel_id_t channel_id, | |
pdma_channel_isr_t handler | |
); | |
/***************************************************************************//** | |
The PDMA_clear_irq() function clears interrupts for a specific PDMA channel. | |
This function also clears the PDMA interrupt in the Cortex-M3 NVIC. | |
@param channel_id | |
The channel_id parameter identifies the PDMA channel used by the function. | |
*/ | |
void PDMA_clear_irq | |
( | |
pdma_channel_id_t channel_id | |
); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif /* __MSS_PERIPHERAL_DMA_H_ */ |